<?php
use Alidayu\AlidayuClient as Client;
use Alidayu\Request\SmsNumSend;
/**
 * 获取当前登录的管事员id
 * @return int
 */
function get_current_admin_id()
{
    return $_SESSION['ADMIN_ID'];
}

/**
 * 获取当前登录的管事员id
 * @return int
 */
function sp_get_current_admin_id()
{
    return get_current_admin_id();
}

/**
 * 判断前台用户是否登录
 * @return boolean
 */
function sp_is_user_login()
{
    return !empty($_SESSION['user']);
}

/**
 * 获取当前登录的前台用户的信息，未登录时，返回false
 * @return array|boolean
 */
function sp_get_current_user()
{
    if (isset($_SESSION['user'])) {
        return $_SESSION['user'];
    } else {
        return false;
    }
}

/**
 * 更新当前登录前台用户的信息
 * @param array $user 前台用户的信息
 */
function sp_update_current_user($user)
{
    $_SESSION['user'] = $user;
}

/**
 * 获取当前登录前台用户id,推荐使用sp_get_current_userid
 * @return int
 */
function get_current_userid()
{

    if (isset($_SESSION['user'])) {
        return $_SESSION['user']['id'];
    } else {
        return 0;
    }
}

/**
 * 获取当前登录前台用户id
 * @return int
 */
function sp_get_current_userid()
{
    return get_current_userid();
}

/**
 * 返回带协议的域名
 */
function sp_get_host()
{
    $host = $_SERVER["HTTP_HOST"];
    $protocol = is_ssl() ? "https://" : "http://";
    return $protocol . $host;
}

/**
 * 获取前台模板根目录
 */
function sp_get_theme_path()
{
    // 获取当前主题名称
    $tmpl_path = C("SP_TMPL_PATH");
    $theme = C('SP_DEFAULT_THEME');
    if (C('TMPL_DETECT_THEME')) {// 自动侦测模板主题
        $t = C('VAR_TEMPLATE');
        if (isset($_GET[$t])) {
            $theme = $_GET[$t];
        } elseif (cookie('think_template')) {
            $theme = cookie('think_template');
        }
        if (!file_exists($tmpl_path . "/" . $theme)) {
            $theme = C('SP_DEFAULT_THEME');
        }
        cookie('think_template', $theme, 864000);
    }

    return __ROOT__ . '/' . $tmpl_path . $theme . "/";
}


/**
 * 获取用户头像相对网站根目录的地址
 */
function sp_get_user_avatar_url($avatar)
{

    if ($avatar) {
        if (strpos($avatar, "http") === 0) {
            return $avatar;
        } else {
            return sp_get_asset_upload_path("avatar/" . $avatar);
        }

    } else {
        return $avatar;
    }

}

/**
 * CMF密码加密方法
 * @param string $pw 要加密的字符串
 * @return string
 */
function sp_password($pw, $authcode = '')
{
    if (empty($authcode)) {
        $authcode = C("AUTHCODE");
    }
    $result = "###" . md5(md5($authcode . $pw));
    return $result;
}

/**
 * CMF密码加密方法 (X2.0.0以前的方法)
 * @param string $pw 要加密的字符串
 * @return string
 */
function sp_password_old($pw)
{
    $decor = md5(C('DB_PREFIX'));
    $mi = md5($pw);
    return substr($decor, 0, 12) . $mi . substr($decor, -4, 4);
}

/**
 * CMF密码比较方法,所有涉及密码比较的地方都用这个方法
 * @param string $password 要比较的密码
 * @param string $password_in_db 数据库保存的已经加密过的密码
 * @return boolean 密码相同，返回true
 */
function sp_compare_password($password, $password_in_db)
{
    if (strpos($password_in_db, "###") === 0) {
        return sp_password($password) == $password_in_db;
    } else {
        return sp_password_old($password) == $password_in_db;
    }
}


function sp_log($content, $file = "log.txt")
{
    file_put_contents($file, $content, FILE_APPEND);
}

/**
 * 随机字符串生成
 * @param int $len 生成的字符串长度
 * @return string
 */
function sp_random_string($len = 6)
{
    $chars = array(
        "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k",
        "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v",
        "w", "x", "y", "z", "A", "B", "C", "D", "E", "F", "G",
        "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R",
        "S", "T", "U", "V", "W", "X", "Y", "Z", "0", "1", "2",
        "3", "4", "5", "6", "7", "8", "9"
    );
    $charsLen = count($chars) - 1;
    shuffle($chars);    // 将数组打乱
    $output = "";
    for ($i = 0; $i < $len; $i++) {
        $output .= $chars[mt_rand(0, $charsLen)];
    }
    return $output;
}

/**
 * 清空系统缓存，兼容sae
 */
function sp_clear_cache()
{
    import("ORG.Util.Dir");
    $dirs = array();
    // runtime/
    $rootdirs = sp_scan_dir(RUNTIME_PATH . "*");
    //$noneed_clear=array(".","..","Data");
    $noneed_clear = array(".", "..");
    $rootdirs = array_diff($rootdirs, $noneed_clear);
    foreach ($rootdirs as $dir) {

        if ($dir != "." && $dir != "..") {
            $dir = RUNTIME_PATH . $dir;
            if (is_dir($dir)) {
                //array_push ( $dirs, $dir );
                $tmprootdirs = sp_scan_dir($dir . "/*");
                foreach ($tmprootdirs as $tdir) {
                    if ($tdir != "." && $tdir != "..") {
                        $tdir = $dir . '/' . $tdir;
                        if (is_dir($tdir)) {
                            array_push($dirs, $tdir);
                        } else {
                            @unlink($tdir);
                        }
                    }
                }
            } else {
                @unlink($dir);
            }
        }
    }
    $dirtool = new \Dir("");
    foreach ($dirs as $dir) {
        $dirtool->delDir($dir);
    }

    if (sp_is_sae()) {
        $global_mc = @memcache_init();
        if ($global_mc) {
            $global_mc->flush();
        }

        $no_need_delete = array("THINKCMF_DYNAMIC_CONFIG");
        $kv = new SaeKV();
        // 初始化KVClient对象
        $ret = $kv->init();
        // 循环获取所有key-values
        $ret = $kv->pkrget('', 100);
        while (true) {
            foreach ($ret as $key => $value) {
                if (!in_array($key, $no_need_delete)) {
                    $kv->delete($key);
                }
            }
            end($ret);
            $start_key = key($ret);
            $i = count($ret);
            if ($i < 100) break;
            $ret = $kv->pkrget('', 100, $start_key);
        }

    }

}

/**
 * 保存数组变量到php文件
 */
function sp_save_var($path, $value)
{
    $ret = file_put_contents($path, "<?php\treturn " . var_export($value, true) . ";?>");
    return $ret;
}

/**
 * 更新系统配置文件
 * @param array $data <br>如：array("URL_MODEL"=>0);
 * @return boolean
 */
function sp_set_dynamic_config($data)
{

    if (!is_array($data)) {
        return false;
    }

    if (sp_is_sae()) {
        $kv = new SaeKV();
        $ret = $kv->init();
        $configs = $kv->get("THINKCMF_DYNAMIC_CONFIG");
        $configs = empty($configs) ? array() : unserialize($configs);
        $configs = array_merge($configs, $data);
        $result = $kv->set('THINKCMF_DYNAMIC_CONFIG', serialize($configs));
    } elseif (defined('IS_BAE') && IS_BAE) {
        $bae_mc = new BaeMemcache();
        $configs = $bae_mc->get("THINKCMF_DYNAMIC_CONFIG");
        $configs = empty($configs) ? array() : unserialize($configs);
        $configs = array_merge($configs, $data);
        $result = $bae_mc->set("THINKCMF_DYNAMIC_CONFIG", serialize($configs), MEMCACHE_COMPRESSED, 0);
    } else {
        $config_file = "./data/conf/config.php";
        if (file_exists($config_file)) {
            $configs = include $config_file;
        } else {
            $configs = array();
        }
        $configs = array_merge($configs, $data);
        $result = file_put_contents($config_file, "<?php\treturn " . var_export($configs, true) . ";");
    }
    sp_clear_cache();
    S("sp_dynamic_config", $configs);
    return $result;
}


/**
 * 生成参数列表,以数组形式返回
 */
function sp_param_lable($tag = '')
{
    $param = array();
    $array = explode(';', $tag);
    foreach ($array as $v) {
        $v = trim($v);
        if (!empty($v)) {
            list($key, $val) = explode(':', $v);
            $param[trim($key)] = trim($val);
        }
    }
    return $param;
}


/**
 * 获取后台管理设置的网站信息，此类信息一般用于前台，推荐使用sp_get_site_options
 */
function get_site_options()
{
    $site_options = F("site_options");
    if (empty($site_options)) {
        $options_obj = M("Options");
        $option = $options_obj->where("option_name='site_options'")->find();
        if ($option) {
            $site_options = json_decode($option['option_value'], true);
        } else {
            $site_options = array();
        }
        F("site_options", $site_options);
    }
    $site_options['site_tongji'] = htmlspecialchars_decode($site_options['site_tongji']);
    return $site_options;
}

/**
 * 获取后台管理设置的网站信息，此类信息一般用于前台
 */
function sp_get_site_options()
{
    get_site_options();
}

/**
 * 获取CMF系统的设置，此类设置用于全局
 * @param string $key 设置key，为空时返回所有配置信息
 * @return mixed
 */
function sp_get_cmf_settings($key = "")
{
    $cmf_settings = F("cmf_settings");
    if (empty($cmf_settings)) {
        $options_obj = M("Options");
        $option = $options_obj->where("option_name='cmf_settings'")->find();
        if ($option) {
            $cmf_settings = json_decode($option['option_value'], true);
        } else {
            $cmf_settings = array();
        }
        F("cmf_settings", $cmf_settings);
    }
    if (!empty($key)) {
        return $cmf_settings[$key];
    }
    return $cmf_settings;
}

/**
 * 更新CMF系统的设置，此类设置用于全局
 * @param array $data
 * @return boolean
 */
function sp_set_cmf_setting($data)
{
    if (!is_array($data) || empty($data)) {
        return false;
    }
    $cmf_settings['option_name'] = "cmf_settings";
    $options_model = M("Options");
    $find_setting = $options_model->where("option_name='cmf_settings'")->find();
    F("cmf_settings", null);
    if ($find_setting) {
        $setting = json_decode($find_setting['option_value'], true);
        if ($setting) {
            $setting = array_merge($setting, $data);
        } else {
            $setting = $data;
        }

        $cmf_settings['option_value'] = json_encode($setting);
        return $options_model->where("option_name='cmf_settings'")->save($cmf_settings);
    } else {
        $cmf_settings['option_value'] = json_encode($data);
        return $options_model->add($cmf_settings);
    }
}


/**
 * 全局获取验证码图片
 * 生成的是个HTML的img标签
 * @param string $imgparam <br>
 * 生成图片样式，可以设置<br>
 * length=4&font_size=20&width=238&height=50&use_curve=1&use_noise=1<br>
 * length:字符长度<br>
 * font_size:字体大小<br>
 * width:生成图片宽度<br>
 * heigh:生成图片高度<br>
 * use_curve:是否画混淆曲线  1:画，0:不画<br>
 * use_noise:是否添加杂点 1:添加，0:不添加<br>
 * @param string $imgattrs <br>
 * img标签原生属性，除src,onclick之外都可以设置<br>
 * 默认值：style="cursor: pointer;" title="点击获取"<br>
 * @return string<br>
 * 原生html的img标签<br>
 * 注，此函数仅生成img标签，应该配合在表单加入name=verify的input标签<br>
 * 如：&lt;input type="text" name="verify"/&gt;<br>
 */
function sp_verifycode_img($imgparam = 'length=4&font_size=20&width=238&height=50&use_curve=1&use_noise=1', $imgattrs = 'style="cursor: pointer;" title="点击获取"')
{
    $src = __ROOT__ . "/index.php?g=api&m=checkcode&a=index&" . $imgparam;
    $img = <<<hello
<img class="verify_img" src="$src" onclick="this.src='$src&time='+Math.random();" $imgattrs/>
hello;
    return $img;
}


/**
 * 返回指定id的菜单
 * 同上一类方法，jquery treeview 风格，可伸缩样式
 * @param $myid 表示获得这个ID下的所有子级
 * @param $effected_id 需要生成treeview目录数的id
 * @param $str 末级样式
 * @param $str2 目录级别样式
 * @param $showlevel 直接显示层级数，其余为异步显示，0为全部限制
 * @param $ul_class 内部ul样式 默认空  可增加其他样式如'sub-menu'
 * @param $li_class 内部li样式 默认空  可增加其他样式如'menu-item'
 * @param $style 目录样式 默认 filetree 可增加其他样式如'filetree treeview-famfamfam'
 * @param $dropdown 有子元素时li的class
 * $id="main";
 * $effected_id="mainmenu";
 * $filetpl="<a href='\$href'><span class='file'>\$label</span></a>";
 * $foldertpl="<span class='folder'>\$label</span>";
 * $ul_class="" ;
 * $li_class="" ;
 * $style="filetree";
 * $showlevel=6;
 * sp_get_menu($id,$effected_id,$filetpl,$foldertpl,$ul_class,$li_class,$style,$showlevel);
 * such as
 * <ul id="example" class="filetree ">
 * <li class="hasChildren" id='1'>
 * <span class='folder'>test</span>
 * <ul>
 * <li class="hasChildren" id='4'>
 * <span class='folder'>caidan2</span>
 * <ul>
 * <li class="hasChildren" id='5'>
 * <span class='folder'>sss</span>
 * <ul>
 * <li id='3'><span class='folder'>test2</span></li>
 * </ul>
 * </li>
 * </ul>
 * </li>
 * </ul>
 * </li>
 * <li class="hasChildren" id='6'><span class='file'>ss</span></li>
 * </ul>
 */

function sp_get_menu($id = "main", $effected_id = "mainmenu", $filetpl = "<span class='file'>\$label</span>", $foldertpl = "<span class='folder'>\$label</span>", $ul_class = "", $li_class = "", $style = "filetree", $showlevel = 6, $dropdown = 'hasChild')
{
    $navs = F("site_nav_" . $id);
    if (empty($navs)) {
        $navs = _sp_get_menu_datas($id);
    }

    import("Tree");
    $tree = new \Tree();
    $tree->init($navs);
    return $tree->get_treeview_menu(0, $effected_id, $filetpl, $foldertpl, $showlevel, $ul_class, $li_class, $style, 1, FALSE, $dropdown);
}


function _sp_get_menu_datas($id)
{
    $nav_obj = M("Nav");
    $oldid = $id;
    $id = intval($id);
    $id = empty($id) ? "main" : $id;
    if ($id == "main") {
        $navcat_obj = M("NavCat");
        $main = $navcat_obj->where("active=1")->find();
        $id = $main['navcid'];
    }

    if (empty($id)) {
        return array();
    }

    $navs = $nav_obj->where(array('cid' => $id, 'status' => 1))->order(array("listorder" => "ASC"))->select();
    foreach ($navs as $key => $nav) {
        $href = htmlspecialchars_decode($nav['href']);
        $hrefold = $href;

        if (strpos($hrefold, "{")) {//序列 化的数据
            $href = unserialize(stripslashes($nav['href']));
            $default_app = strtolower(C("DEFAULT_MODULE"));
            $href = strtolower(leuu($href['action'], $href['param']));
            $g = C("VAR_MODULE");
            $href = preg_replace("/\/$default_app\//", "/", $href);
            $href = preg_replace("/$g=$default_app&/", "", $href);
        } else {
            if ($hrefold == "home") {
                $href = __ROOT__ . "/";
            } else {
                $href = $hrefold;
            }
        }
        $nav['href'] = $href;
        $navs[$key] = $nav;
    }
    F("site_nav_" . $oldid, $navs);
    return $navs;
}


function sp_get_menu_tree($id = "main")
{
    $navs = F("site_nav_" . $id);
    if (empty($navs)) {
        $navs = _sp_get_menu_datas($id);
    }

    import("Tree");
    $tree = new \Tree();
    $tree->init($navs);
    return $tree->get_tree_array(0, "");
}


/**
 *获取html文本里的img
 * @param string $content
 * @return array
 */
function sp_getcontent_imgs($content)
{
    import("phpQuery");
    \phpQuery::newDocumentHTML($content);
    $pq = pq();
    $imgs = $pq->find("img");
    $imgs_data = array();
    if ($imgs->length()) {
        foreach ($imgs as $img) {
            $img = pq($img);
            $im['src'] = $img->attr("src");
            $im['title'] = $img->attr("title");
            $im['alt'] = $img->attr("alt");
            $imgs_data[] = $im;
        }
    }
    \phpQuery::$documents = null;
    return $imgs_data;
}


/**
 *
 * @param unknown_type $navcatname
 * @param unknown_type $datas
 * @param unknown_type $navrule
 * @return string
 */
function sp_get_nav4admin($navcatname, $datas, $navrule)
{
    $nav['name'] = $navcatname;
    $nav['urlrule'] = $navrule;
    foreach ($datas as $t) {
        $urlrule = array();
        $group = strtolower(MODULE_NAME) == strtolower(C("DEFAULT_MODULE")) ? "" : MODULE_NAME . "/";
        $action = $group . $navrule['action'];
        $urlrule['action'] = MODULE_NAME . "/" . $navrule['action'];
        $urlrule['param'] = array();
        if (isset($navrule['param'])) {
            foreach ($navrule['param'] as $key => $val) {
                $urlrule['param'][$key] = $t[$val];
            }
        }

        $nav['items'][] = array(
            "label" => $t[$navrule['label']],
            "url" => U($action, $urlrule['param']),
            "rule" => serialize($urlrule)
        );
    }
    return json_encode($nav);
}

function sp_get_apphome_tpl($tplname, $default_tplname, $default_theme = "")
{
    $theme = C('SP_DEFAULT_THEME');
    if (C('TMPL_DETECT_THEME')) {// 自动侦测模板主题
        $t = C('VAR_TEMPLATE');
        if (isset($_GET[$t])) {
            $theme = $_GET[$t];
        } elseif (cookie('think_template')) {
            $theme = cookie('think_template');
        }
    }
    $theme = empty($default_theme) ? $theme : $default_theme;
    $themepath = C("SP_TMPL_PATH") . $theme . "/" . MODULE_NAME . "/";
    $tplpath = sp_add_template_file_suffix($themepath . $tplname);
    $defaultpl = sp_add_template_file_suffix($themepath . $default_tplname);
    if (file_exists_case($tplpath)) {
    } else if (file_exists_case($defaultpl)) {
        $tplname = $default_tplname;
    } else {
        $tplname = "404";
    }
    return $tplname;
}


/**
 * 去除字符串中的指定字符
 * @param string $str 待处理字符串
 * @param string $chars 需去掉的特殊字符
 * @return string
 */
function sp_strip_chars($str, $chars = '?<*.>\'\"')
{
    return preg_replace('/[' . $chars . ']/is', '', $str);
}

/**
 * 发送邮件
 * @param string $address
 * @param string $subject
 * @param string $message
 * @return array<br>
 * 返回格式：<br>
 * array(<br>
 *    "error"=>0|1,//0代表出错<br>
 *    "message"=> "出错信息"<br>
 * );
 */
function sp_send_email($address, $subject, $message)
{
    import("PHPMailer");
    $mail = new \PHPMailer();
    // 设置PHPMailer使用SMTP服务器发送Email
    $mail->IsSMTP();
    $mail->IsHTML(true);
    // 设置邮件的字符编码，若不指定，则为'UTF-8'
    $mail->CharSet = 'UTF-8';
    // 添加收件人地址，可以多次使用来添加多个收件人
    $mail->AddAddress($address);
    // 设置邮件正文
    $mail->Body = $message;
    // 设置邮件头的From字段。
    $mail->From = C('SP_MAIL_ADDRESS');
    // 设置发件人名字
    $mail->FromName = C('SP_MAIL_SENDER');;
    // 设置邮件标题
    $mail->Subject = $subject;
    // 设置SMTP服务器。
    $mail->Host = C('SP_MAIL_SMTP');
    // 设置SMTP服务器端口。
    $port = C('SP_MAIL_SMTP_PORT');
    $mail->Port = empty($port) ? "25" : $port;
    // 设置为"需要验证"
    $mail->SMTPAuth = true;
    // 设置用户名和密码。
    $mail->Username = C('SP_MAIL_LOGINNAME');
    $mail->Password = C('SP_MAIL_PASSWORD');
    // 发送邮件。
    if (!$mail->Send()) {
        $mailerror = $mail->ErrorInfo;
        return array("error" => 1, "message" => $mailerror);
    } else {
        return array("error" => 0, "message" => "success");
    }
}

/**
 * 转化数据库保存的文件路径，为可以访问的url
 * @param string $file
 * @param boolean $withhost
 * @return string
 */
function sp_get_asset_upload_path($file, $withhost = false)
{
    if (strpos($file, "http") === 0) {
        return $file;
    } else if (strpos($file, "/") === 0) {
        return $file;
    } else {
        $filepath = C("TMPL_PARSE_STRING.__UPLOAD__") . $file;
        if ($withhost) {
            if (strpos($filepath, "http") !== 0) {
                $http = 'http://';
                $http = is_ssl() ? 'https://' : $http;
                $filepath = $http . $_SERVER['HTTP_HOST'] . $filepath;
            }
        }
        return $filepath;

    }

}


function sp_authcode($string, $operation = 'DECODE', $key = '', $expiry = 0)
{
    $ckey_length = 4;

    $key = md5($key ? $key : C("AUTHCODE"));
    $keya = md5(substr($key, 0, 16));
    $keyb = md5(substr($key, 16, 16));
    $keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length) : substr(md5(microtime()), -$ckey_length)) : '';

    $cryptkey = $keya . md5($keya . $keyc);
    $key_length = strlen($cryptkey);

    $string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0) . substr(md5($string . $keyb), 0, 16) . $string;
    $string_length = strlen($string);

    $result = '';
    $box = range(0, 255);

    $rndkey = array();
    for ($i = 0; $i <= 255; $i++) {
        $rndkey[$i] = ord($cryptkey[$i % $key_length]);
    }

    for ($j = $i = 0; $i < 256; $i++) {
        $j = ($j + $box[$i] + $rndkey[$i]) % 256;
        $tmp = $box[$i];
        $box[$i] = $box[$j];
        $box[$j] = $tmp;
    }

    for ($a = $j = $i = 0; $i < $string_length; $i++) {
        $a = ($a + 1) % 256;
        $j = ($j + $box[$a]) % 256;
        $tmp = $box[$a];
        $box[$a] = $box[$j];
        $box[$j] = $tmp;
        $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
    }

    if ($operation == 'DECODE') {
        if ((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26) . $keyb), 0, 16)) {
            return substr($result, 26);
        } else {
            return '';
        }
    } else {
        return $keyc . str_replace('=', '', base64_encode($result));
    }

}

function sp_authencode($string)
{
    return sp_authcode($string, "ENCODE");
}

function Comments($table, $post_id, $params = array())
{
    return R("Comment/Widget/index", array($table, $post_id, $params));
}

/**
 * 获取评论
 * @param string $tag
 * @param array $where //按照thinkphp where array格式
 */
function sp_get_comments($tag = "field:*;limit:0,5;order:createtime desc;", $where = array())
{
    $where = array();
    $tag = sp_param_lable($tag);
    $field = !empty($tag['field']) ? $tag['field'] : '*';
    $limit = !empty($tag['limit']) ? $tag['limit'] : '5';
    $order = !empty($tag['order']) ? $tag['order'] : 'createtime desc';

    //根据参数生成查询条件
    $mwhere['status'] = array('eq', 1);

    if (is_array($where)) {
        $where = array_merge($mwhere, $where);
    } else {
        $where = $mwhere;
    }

    $comments_model = M("Comments");

    $comments = $comments_model->field($field)->where($where)->order($order)->limit($limit)->select();
    return $comments;
}

function sp_file_write($file, $content)
{

    if (sp_is_sae()) {
        $s = new SaeStorage();
        $arr = explode('/', ltrim($file, './'));
        $domain = array_shift($arr);
        $save_path = implode('/', $arr);
        return $s->write($domain, $save_path, $content);
    } else {
        try {
            $fp2 = @fopen($file, "w");
            fwrite($fp2, $content);
            fclose($fp2);
            return true;
        } catch (Exception $e) {
            return false;
        }
    }
}

function sp_file_read($file)
{
    if (sp_is_sae()) {
        $s = new SaeStorage();
        $arr = explode('/', ltrim($file, './'));
        $domain = array_shift($arr);
        $save_path = implode('/', $arr);
        return $s->read($domain, $save_path);
    } else {
        file_get_contents($file);
    }
}

/*修复缩略图使用网络地址时，会出现的错误。5iymt 2015年7月10日*/
function sp_asset_relative_url($asset_url)
{
    if (strpos($asset_url, "http") === 0) {
        return $asset_url;
    } else {
        return str_replace(C("TMPL_PARSE_STRING.__UPLOAD__"), "", $asset_url);
    }
}

function sp_content_page($content, $pagetpl = '{first}{prev}{liststart}{list}{listend}{next}{last}')
{
    $contents = explode('_ueditor_page_break_tag_', $content);
    $totalsize = count($contents);
    import('Page');
    $pagesize = 1;
    $PageParam = C("VAR_PAGE");
    $page = new \Page($totalsize, $pagesize);
    $page->setLinkWraper("li");
    $page->SetPager('default', $pagetpl, array("listlong" => "9", "first" => "首页", "last" => "尾页", "prev" => "上一页", "next" => "下一页", "list" => "*", "disabledclass" => ""));
    $content = $contents[$page->firstRow];
    $data['content'] = $content;
    $data['page'] = $page->show('default');

    return $data;
}


/**
 * 根据广告名称获取广告内容
 * @param string $ad
 * @return 广告内容
 */

function sp_getad($ad)
{
    $ad_obj = M("Ad");
    $ad = $ad_obj->field("ad_content")->where("ad_name='$ad' and status=1")->find();
    return htmlspecialchars_decode($ad['ad_content']);
}

/**
 * 根据幻灯片标识获取所有幻灯片
 * @param string $slide 幻灯片标识
 * @return array;
 */
function sp_getslide($slide, $limit = 5, $order = "listorder ASC")
{
    $slide_obj = M("SlideCat");
    $join = "" . C('DB_PREFIX') . 'slide as b on ' . C('DB_PREFIX') . 'slide_cat.cid =b.slide_cid';
    if ($order == '') {
        $order = "listorder ASC";
    }
    if ($limit == 0) {
        $limit = 5;
    }
    return $slide_obj->join($join)->where("cat_idname='$slide' and slide_status=1")->order($order)->limit('0,' . $limit)->select();

}

/**
 * 获取所有友情连接
 * @return array
 */
function sp_getlinks()
{
    $links_obj = M("Links");
    return $links_obj->where("link_status=1")->order("listorder ASC")->select();
}

/**
 * 检查用户对某个url,内容的可访问性，用于记录如是否赞过，是否访问过等等;开发者可以自由控制，对于没有必要做的检查可以不做，以减少服务器压力
 * @param number $object 访问对象的id,格式：不带前缀的表名+id;如posts1表示xx_posts表里id为1的记录;如果object为空，表示只检查对某个url访问的合法性
 * @param number $count_limit 访问次数限制,如1，表示只能访问一次
 * @param boolean $ip_limit ip限制,false为不限制，true为限制
 * @param number $expire 距离上次访问的最小时间单位s，0表示不限制，大于0表示最后访问$expire秒后才可以访问
 * @return true 可访问，false不可访问
 */
function sp_check_user_action($object = "", $count_limit = 1, $ip_limit = false, $expire = 0)
{
    $common_action_log_model = M("CommonActionLog");
    $action = MODULE_NAME . "-" . CONTROLLER_NAME . "-" . ACTION_NAME;
    $userid = get_current_userid();

    $ip = get_client_ip(0, true);//修复ip获取

    $where = array("user" => $userid, "action" => $action, "object" => $object);
    if ($ip_limit) {
        $where['ip'] = $ip;
    }

    $find_log = $common_action_log_model->where($where)->find();

    $time = time();
    if ($find_log) {
        $common_action_log_model->where($where)->save(array("count" => array("exp", "count+1"), "last_time" => $time, "ip" => $ip));
        if ($find_log['count'] >= $count_limit) {
            return false;
        }

        if ($expire > 0 && ($time - $find_log['last_time']) < $expire) {
            return false;
        }
    } else {
        $common_action_log_model->add(array("user" => $userid, "action" => $action, "object" => $object, "count" => array("exp", "count+1"), "last_time" => $time, "ip" => $ip));
    }

    return true;
}

/**
 * 用于生成收藏内容用的key
 * @param string $table 收藏内容所在表
 * @param int $object_id 收藏内容的id
 */
function sp_get_favorite_key($table, $object_id)
{
    $auth_code = C("AUTHCODE");
    $string = "$auth_code $table $object_id";

    return sp_authencode($string);
}


function sp_get_relative_url($url)
{
    if (strpos($url, "http") === 0) {
        $url = str_replace(array("https://", "http://"), "", $url);

        $pos = strpos($url, "/");
        if ($pos === false) {
            return "";
        } else {
            $url = substr($url, $pos + 1);
            $root = preg_replace("/^\//", "", __ROOT__);
            $root = str_replace("/", "\/", $root);
            $url = preg_replace("/^" . $root . "\//", "", $url);
            return $url;
        }
    }
    return $url;
}

/**
 *
 * @param string $tag
 * @param array $where
 * @return array
 */

function sp_get_users($tag = "field:*;limit:0,8;order:create_time desc;", $where = array())
{
    $where = array();
    $tag = sp_param_lable($tag);
    $field = !empty($tag['field']) ? $tag['field'] : '*';
    $limit = !empty($tag['limit']) ? $tag['limit'] : '8';
    $order = !empty($tag['order']) ? $tag['order'] : 'create_time desc';

    //根据参数生成查询条件
    $mwhere['user_status'] = array('eq', 1);
    $mwhere['user_type'] = array('eq', 2);//default user

    if (is_array($where)) {
        $where = array_merge($mwhere, $where);
    } else {
        $where = $mwhere;
    }

    $users_model = M("Users");

    $users = $users_model->field($field)->where($where)->order($order)->limit($limit)->select();
    return $users;
}

/**
 * URL组装 支持不同URL模式
 * @param string $url URL表达式，格式：'[模块/控制器/操作#锚点@域名]?参数1=值1&参数2=值2...'
 * @param string|array $vars 传入的参数，支持数组和字符串
 * @param string $suffix 伪静态后缀，默认为true表示获取配置值
 * @param boolean $domain 是否显示域名
 * @return string
 */
function leuu($url = '', $vars = '', $suffix = true, $domain = false)
{
    $routes = sp_get_routes();
    if (empty($routes)) {
        return U($url, $vars, $suffix, $domain);
    } else {
        // 解析URL
        $info = parse_url($url);
        $url = !empty($info['path']) ? $info['path'] : ACTION_NAME;
        if (isset($info['fragment'])) { // 解析锚点
            $anchor = $info['fragment'];
            if (false !== strpos($anchor, '?')) { // 解析参数
                list($anchor, $info['query']) = explode('?', $anchor, 2);
            }
            if (false !== strpos($anchor, '@')) { // 解析域名
                list($anchor, $host) = explode('@', $anchor, 2);
            }
        } elseif (false !== strpos($url, '@')) { // 解析域名
            list($url, $host) = explode('@', $info['path'], 2);
        }

        // 解析子域名
        //TODO?

        // 解析参数
        if (is_string($vars)) { // aaa=1&bbb=2 转换成数组
            parse_str($vars, $vars);
        } elseif (!is_array($vars)) {
            $vars = array();
        }
        if (isset($info['query'])) { // 解析地址里面参数 合并到vars
            parse_str($info['query'], $params);
            $vars = array_merge($params, $vars);
        }

        $vars_src = $vars;

        ksort($vars);

        // URL组装
        $depr = C('URL_PATHINFO_DEPR');
        $urlCase = C('URL_CASE_INSENSITIVE');
        if ('/' != $depr) { // 安全替换
            $url = str_replace('/', $depr, $url);
        }
        // 解析模块、控制器和操作
        $url = trim($url, $depr);
        $path = explode($depr, $url);
        $var = array();
        $varModule = C('VAR_MODULE');
        $varController = C('VAR_CONTROLLER');
        $varAction = C('VAR_ACTION');
        $var[$varAction] = !empty($path) ? array_pop($path) : ACTION_NAME;
        $var[$varController] = !empty($path) ? array_pop($path) : CONTROLLER_NAME;
        if ($maps = C('URL_ACTION_MAP')) {
            if (isset($maps[strtolower($var[$varController])])) {
                $maps = $maps[strtolower($var[$varController])];
                if ($action = array_search(strtolower($var[$varAction]), $maps)) {
                    $var[$varAction] = $action;
                }
            }
        }
        if ($maps = C('URL_CONTROLLER_MAP')) {
            if ($controller = array_search(strtolower($var[$varController]), $maps)) {
                $var[$varController] = $controller;
            }
        }
        if ($urlCase) {
            $var[$varController] = parse_name($var[$varController]);
        }
        $module = '';

        if (!empty($path)) {
            $var[$varModule] = array_pop($path);
        } else {
            if (C('MULTI_MODULE')) {
                if (MODULE_NAME != C('DEFAULT_MODULE') || !C('MODULE_ALLOW_LIST')) {
                    $var[$varModule] = MODULE_NAME;
                }
            }
        }
        if ($maps = C('URL_MODULE_MAP')) {
            if ($_module = array_search(strtolower($var[$varModule]), $maps)) {
                $var[$varModule] = $_module;
            }
        }
        if (isset($var[$varModule])) {
            $module = $var[$varModule];
        }

        if (C('URL_MODEL') == 0) { // 普通模式URL转换
            $url = __APP__ . '?' . http_build_query(array_reverse($var));

            if ($urlCase) {
                $url = strtolower($url);
            }
            if (!empty($vars)) {
                $vars = http_build_query($vars);
                $url .= '&' . $vars;
            }
        } else { // PATHINFO模式或者兼容URL模式

            if (empty($var[C('VAR_MODULE')])) {
                $var[C('VAR_MODULE')] = MODULE_NAME;
            }

            $module_controller_action = strtolower(implode($depr, array_reverse($var)));

            $has_route = false;
            $original_url = $module_controller_action . (empty($vars) ? "" : "?") . http_build_query($vars);

            if (isset($routes['static'][$original_url])) {
                $has_route = true;
                $url = __APP__ . "/" . $routes['static'][$original_url];
            } else {
                if (isset($routes['dynamic'][$module_controller_action])) {
                    $urlrules = $routes['dynamic'][$module_controller_action];

                    $empty_query_urlrule = array();

                    foreach ($urlrules as $ur) {
                        $intersect = array_intersect_assoc($ur['query'], $vars);
                        if ($intersect) {
                            $vars = array_diff_key($vars, $ur['query']);
                            $url = $ur['url'];
                            $has_route = true;
                            break;
                        }
                        if (empty($empty_query_urlrule) && empty($ur['query'])) {
                            $empty_query_urlrule = $ur;
                        }
                    }

                    if (!empty($empty_query_urlrule)) {
                        $has_route = true;
                        $url = $empty_query_urlrule['url'];
                    }

                    $new_vars = array_reverse($vars);
                    foreach ($new_vars as $key => $value) {
                        if (strpos($url, ":$key") !== false) {
                            $url = str_replace(":$key", $value, $url);
                            unset($vars[$key]);
                        }
                    }
                    $url = str_replace(array("\d", "$"), "", $url);

                    if ($has_route) {
                        if (!empty($vars)) { // 添加参数
                            foreach ($vars as $var => $val) {
                                if ('' !== trim($val)) $url .= $depr . $var . $depr . urlencode($val);
                            }
                        }
                        $url = __APP__ . "/" . $url;
                    }
                }
            }

            $url = str_replace(array("^", "$"), "", $url);

            if (!$has_route) {
                $module = defined('BIND_MODULE') ? '' : $module;
                $url = __APP__ . '/' . implode($depr, array_reverse($var));

                if ($urlCase) {
                    $url = strtolower($url);
                }

                if (!empty($vars)) { // 添加参数
                    foreach ($vars as $var => $val) {
                        if ('' !== trim($val)) $url .= $depr . $var . $depr . urlencode($val);
                    }
                }
            }


            if ($suffix) {
                $suffix = $suffix === true ? C('URL_HTML_SUFFIX') : $suffix;
                if ($pos = strpos($suffix, '|')) {
                    $suffix = substr($suffix, 0, $pos);
                }
                if ($suffix && '/' != substr($url, -1)) {
                    $url .= '.' . ltrim($suffix, '.');
                }
            }
        }

        if (isset($anchor)) {
            $url .= '#' . $anchor;
        }
        if ($domain) {
            $url = (is_ssl() ? 'https://' : 'http://') . $domain . $url;
        }

        return $url;
    }
}

/**
 * URL组装 支持不同URL模式
 * @param string $url URL表达式，格式：'[模块/控制器/操作#锚点@域名]?参数1=值1&参数2=值2...'
 * @param string|array $vars 传入的参数，支持数组和字符串
 * @param string $suffix 伪静态后缀，默认为true表示获取配置值
 * @param boolean $domain 是否显示域名
 * @return string
 */
function UU($url = '', $vars = '', $suffix = true, $domain = false)
{
    return leuu($url, $vars, $suffix, $domain);
}


function sp_get_routes($refresh = false)
{
    $routes = F("routes");

    if ((!empty($routes) || is_array($routes)) && !$refresh) {
        return $routes;
    }
    $routes = M("Route")->where("status=1")->order("listorder asc")->select();
    $all_routes = array();
    $cache_routes = array();
    foreach ($routes as $er) {
        $full_url = htmlspecialchars_decode($er['full_url']);

        // 解析URL
        $info = parse_url($full_url);

        $path = explode("/", $info['path']);
        if (count($path) != 3) {//必须是完整 url
            continue;
        }

        $module = strtolower($path[0]);

        // 解析参数
        $vars = array();
        if (isset($info['query'])) { // 解析地址里面参数 合并到vars
            parse_str($info['query'], $params);
            $vars = array_merge($params, $vars);
        }

        $vars_src = $vars;

        ksort($vars);

        $path = $info['path'];

        $full_url = $path . (empty($vars) ? "" : "?") . http_build_query($vars);

        $url = $er['url'];

        if (strpos($url, ':') === false) {
            $cache_routes['static'][$full_url] = $url;
        } else {
            $cache_routes['dynamic'][$path][] = array("query" => $vars, "url" => $url);
        }

        $all_routes[$url] = $full_url;

    }
    F("routes", $cache_routes);
    $route_dir = SITE_PATH . "/data/conf/";
    if (!file_exists($route_dir)) {
        mkdir($route_dir);
    }

    $route_file = $route_dir . "route.php";

    file_put_contents($route_file, "<?php\treturn " . stripslashes(var_export($all_routes, true)) . ";");

    return $cache_routes;


}

/**
 * 判断是否为手机访问
 * @return  boolean
 */
function sp_is_mobile()
{
    static $sp_is_mobile;

    if (isset($sp_is_mobile))
        return $sp_is_mobile;

    if (empty($_SERVER['HTTP_USER_AGENT'])) {
        $sp_is_mobile = false;
    } elseif (strpos($_SERVER['HTTP_USER_AGENT'], 'Mobile') !== false // many mobile devices (all iPhone, iPad, etc.)
        || strpos($_SERVER['HTTP_USER_AGENT'], 'Android') !== false
        || strpos($_SERVER['HTTP_USER_AGENT'], 'Silk/') !== false
        || strpos($_SERVER['HTTP_USER_AGENT'], 'Kindle') !== false
        || strpos($_SERVER['HTTP_USER_AGENT'], 'BlackBerry') !== false
        || strpos($_SERVER['HTTP_USER_AGENT'], 'Opera Mini') !== false
        || strpos($_SERVER['HTTP_USER_AGENT'], 'Opera Mobi') !== false
    ) {
        $sp_is_mobile = true;
    } else {
        $sp_is_mobile = false;
    }

    return $sp_is_mobile;
}

/**
 * 处理插件钩子
 * @param string $hook 钩子名称
 * @param mixed $params 传入参数
 * @return void
 */
function hook($hook, $params = array())
{
    tag($hook, $params);
}

/**
 * 处理插件钩子,只执行一个
 * @param string $hook 钩子名称
 * @param mixed $params 传入参数
 * @return void
 */
function hook_one($hook, $params = array())
{
    return \Think\Hook::listen_one($hook, $params);
}


/**
 * 获取插件类的类名
 * @param strng $name 插件名
 */
function sp_get_plugin_class($name)
{
    $class = "plugins\\{$name}\\{$name}Plugin";
    return $class;
}

/**
 * 获取插件类的配置
 * @param string $name 插件名
 * @return array
 */
function sp_get_plugin_config($name)
{
    $class = sp_get_plugin_class($name);
    if (class_exists($class)) {
        $plugin = new $class();
        return $plugin->getConfig();
    } else {
        return array();
    }
}

/**
 * 替代scan_dir的方法
 * @param string $pattern 检索模式 搜索模式 *.txt,*.doc; (同glog方法)
 * @param int $flags
 */
function sp_scan_dir($pattern, $flags = null)
{
    $files = array_map('basename', glob($pattern, $flags));
    return $files;
}

/**
 * 获取所有钩子，包括系统，应用，模板
 */
function sp_get_hooks($refresh = false)
{
    if (!$refresh) {
        $return_hooks = F('all_hooks');
        if (!empty($return_hooks)) {
            return $return_hooks;
        }
    }

    $return_hooks = array();
    $system_hooks = array(
        "url_dispatch", "app_init", "app_begin", "app_end",
        "action_begin", "action_end", "module_check", "path_info",
        "template_filter", "view_begin", "view_end", "view_parse",
        "view_filter", "body_start", "footer", "footer_end", "sider", "comment", 'admin_home'
    );

    $app_hooks = array();

    $apps = sp_scan_dir(SPAPP . "*", GLOB_ONLYDIR);
    foreach ($apps as $app) {
        $hooks_file = SPAPP . $app . "/hooks.php";
        if (is_file($hooks_file)) {
            $hooks = include $hooks_file;
            $app_hooks = is_array($hooks) ? array_merge($app_hooks, $hooks) : $app_hooks;
        }
    }

    $tpl_hooks = array();

    $tpls = sp_scan_dir("themes/*", GLOB_ONLYDIR);

    foreach ($tpls as $tpl) {
        $hooks_file = sp_add_template_file_suffix("themes/$tpl/hooks");
        if (file_exists_case($hooks_file)) {
            $hooks = file_get_contents($hooks_file);
            $hooks = preg_replace("/[^0-9A-Za-z_-]/u", ",", $hooks);
            $hooks = explode(",", $hooks);
            $hooks = array_filter($hooks);
            $tpl_hooks = is_array($hooks) ? array_merge($tpl_hooks, $hooks) : $tpl_hooks;
        }
    }

    $return_hooks = array_merge($system_hooks, $app_hooks, $tpl_hooks);

    $return_hooks = array_unique($return_hooks);

    F('all_hooks', $return_hooks);
    return $return_hooks;

}


/**
 * 生成访问插件的url
 * @param string $url url 格式：插件名://控制器名/方法
 * @param array $param 参数
 */
function sp_plugin_url($url, $param = array(), $domain = false)
{
    $url = parse_url($url);
    $case = C('URL_CASE_INSENSITIVE');
    $plugin = $case ? parse_name($url['scheme']) : $url['scheme'];
    $controller = $case ? parse_name($url['host']) : $url['host'];
    $action = trim($case ? strtolower($url['path']) : $url['path'], '/');

    /* 解析URL带的参数 */
    if (isset($url['query'])) {
        parse_str($url['query'], $query);
        $param = array_merge($query, $param);
    }

    /* 基础参数 */
    $params = array(
        '_plugin' => $plugin,
        '_controller' => $controller,
        '_action' => $action,
    );
    $params = array_merge($params, $param); //添加额外参数

    return U('api/plugin/execute', $params, true, $domain);
}

/**
 * 检查权限
 * @param name string|array  需要验证的规则列表,支持逗号分隔的权限规则或索引数组
 * @param uid  int           认证用户的id
 * @param relation string    如果为 'or' 表示满足任一条规则即通过验证;如果为 'and'则表示需满足所有规则才能通过验证
 * @return boolean           通过验证返回true;失败返回false
 */
function sp_auth_check($uid, $name = null, $relation = 'or')
{
    if (empty($uid)) {
        return false;
    }

    $iauth_obj = new \Common\Lib\iAuth();
    if (empty($name)) {
        $name = strtolower(MODULE_NAME . "/" . CONTROLLER_NAME . "/" . ACTION_NAME);
    }
    return $iauth_obj->check($uid, $name, $relation);
}

/**
 * 兼容之前版本的ajax的转化方法，如果你之前用参数只有两个可以不用这个转化，如有两个以上的参数请升级一下
 * @param array $data
 * @param string $info
 * @param int $status
 */
function sp_ajax_return($data, $info, $status)
{
    $return = array();
    $return['data'] = $data;
    $return['info'] = $info;
    $return['status'] = $status;
    $data = $return;

    return $data;
}

/**
 * 判断是否为SAE
 */
function sp_is_sae()
{
    if (defined('APP_MODE') && APP_MODE == 'sae') {
        return true;
    } else {
        return false;
    }
}


function sp_alpha_id($in, $to_num = false, $pad_up = 4, $passKey = null)
{
    $index = "aBcDeFgHiJkLmNoPqRsTuVwXyZAbCdEfGhIjKlMnOpQrStUvWxYz0123456789";
    if ($passKey !== null) {
        // Although this function's purpose is to just make the
        // ID short - and not so much secure,
        // with this patch by Simon Franz (http://blog.snaky.org/)
        // you can optionally supply a password to make it harder
        // to calculate the corresponding numeric ID

        for ($n = 0; $n < strlen($index); $n++) $i[] = substr($index, $n, 1);

        $passhash = hash('sha256', $passKey);
        $passhash = (strlen($passhash) < strlen($index)) ? hash('sha512', $passKey) : $passhash;

        for ($n = 0; $n < strlen($index); $n++) $p[] = substr($passhash, $n, 1);

        array_multisort($p, SORT_DESC, $i);
        $index = implode($i);
    }

    $base = strlen($index);

    if ($to_num) {
        // Digital number  <<--  alphabet letter code
        $in = strrev($in);
        $out = 0;
        $len = strlen($in) - 1;
        for ($t = 0; $t <= $len; $t++) {
            $bcpow = pow($base, $len - $t);
            $out = $out + strpos($index, substr($in, $t, 1)) * $bcpow;
        }

        if (is_numeric($pad_up)) {
            $pad_up--;
            if ($pad_up > 0) $out -= pow($base, $pad_up);
        }
        $out = sprintf('%F', $out);
        $out = substr($out, 0, strpos($out, '.'));
    } else {
        // Digital number  -->>  alphabet letter code
        if (is_numeric($pad_up)) {
            $pad_up--;
            if ($pad_up > 0) $in += pow($base, $pad_up);
        }

        $out = "";
        for ($t = floor(log($in, $base)); $t >= 0; $t--) {
            $bcp = pow($base, $t);
            $a = floor($in / $bcp) % $base;
            $out = $out . substr($index, $a, 1);
            $in = $in - ($a * $bcp);
        }
        $out = strrev($out); // reverse
    }

    return $out;
}

/**
 * 验证码检查，验证完后销毁验证码增加安全性 ,<br>返回true验证码正确，false验证码错误
 * @return boolean <br>true：验证码正确，false：验证码错误
 */
function sp_check_verify_code()
{
    $verify = new \Think\Verify();
    return $verify->check($_REQUEST['verify'], "");
}

/**
 * 手机验证码检查，验证完后销毁验证码增加安全性 ,<br>返回true验证码正确，false验证码错误
 * @return boolean <br>true：手机验证码正确，false：手机验证码错误
 */
function sp_check_mobile_verify_code()
{
    return true;
}


/**
 * 执行SQL文件  sae 环境下file_get_contents() 函数好像有间歇性bug。
 * @param string $sql_path sql文件路径
 * @author 5iymt <1145769693@qq.com>
 */
function sp_execute_sql_file($sql_path)
{

    $context = stream_context_create(array(
        'http' => array(
            'timeout' => 30
        )
    ));// 超时时间，单位为秒

    // 读取SQL文件
    $sql = file_get_contents($sql_path, 0, $context);
    $sql = str_replace("\r", "\n", $sql);
    $sql = explode(";\n", $sql);

    // 替换表前缀
    $orginal = 'sp_';
    $prefix = C('DB_PREFIX');
    $sql = str_replace("{$orginal}", "{$prefix}", $sql);

    // 开始安装
    foreach ($sql as $value) {
        $value = trim($value);
        if (empty ($value)) {
            continue;
        }
        $res = M()->execute($value);
    }
}

/**
 * 插件R方法扩展 建立多插件之间的互相调用。提供无限可能
 * 使用方式 get_plugns_return('Chat://Index/index',array())
 * @param string $url 调用地址
 * @param array $params 调用参数
 * @author 5iymt <1145769693@qq.com>
 */
function sp_get_plugins_return($url, $params = array())
{
    $url = parse_url($url);
    $case = C('URL_CASE_INSENSITIVE');
    $plugin = $case ? parse_name($url['scheme']) : $url['scheme'];
    $controller = $case ? parse_name($url['host']) : $url['host'];
    $action = trim($case ? strtolower($url['path']) : $url['path'], '/');

    /* 解析URL带的参数 */
    if (isset($url['query'])) {
        parse_str($url['query'], $query);
        $params = array_merge($query, $params);
    }
    return R("plugins://{$plugin}/{$controller}/{$action}", $params);
}

/**
 * 给没有后缀的模板文件，添加后缀名
 * @param string $filename_nosuffix
 */
function sp_add_template_file_suffix($filename_nosuffix)
{


    if (file_exists_case($filename_nosuffix . C('TMPL_TEMPLATE_SUFFIX'))) {
        $filename_nosuffix = $filename_nosuffix . C('TMPL_TEMPLATE_SUFFIX');
    } else if (file_exists_case($filename_nosuffix . ".php")) {
        $filename_nosuffix = $filename_nosuffix . ".php";
    } else {
        $filename_nosuffix = $filename_nosuffix . C('TMPL_TEMPLATE_SUFFIX');
    }

    return $filename_nosuffix;
}

/**
 * 获取当前主题名
 * @param string $default_theme 指定的默认模板名
 * @return string
 */
function sp_get_current_theme($default_theme = '')
{
    $theme = C('SP_DEFAULT_THEME');
    if (C('TMPL_DETECT_THEME')) {// 自动侦测模板主题
        $t = C('VAR_TEMPLATE');
        if (isset($_GET[$t])) {
            $theme = $_GET[$t];
        } elseif (cookie('think_template')) {
            $theme = cookie('think_template');
        }
    }
    $theme = empty($default_theme) ? $theme : $default_theme;

    return $theme;
}

/**
 * 判断模板文件是否存在，区分大小写
 * @param string $file 模板文件路径，相对于当前模板根目录，不带模板后缀名
 */
function sp_template_file_exists($file)
{
    $theme = sp_get_current_theme();
    $filepath = C("SP_TMPL_PATH") . $theme . "/" . $file;
    $tplpath = sp_add_template_file_suffix($filepath);

    if (file_exists_case($tplpath)) {
        return true;
    } else {
        return false;
    }

}

/**
 *根据菜单id获得菜单的详细信息，可以整合进获取菜单数据的方法(_sp_get_menu_datas)中。
 * @param num $id 菜单id，每个菜单id
 * @author 5iymt <1145769693@qq.com>
 */
function sp_get_menu_info($id, $navdata = false)
{
    if (empty($id) && $navdata) {
        //若菜单id不存在，且菜单数据存在。
        $nav = $navdata;
    } else {
        $nav_obj = M("Nav");
        $id = intval($id);
        $nav = $nav_obj->where("id=$id")->find();//菜单数据
    }

    $href = htmlspecialchars_decode($nav['href']);
    $hrefold = $href;

    if (strpos($hrefold, "{")) {//序列 化的数据
        $href = unserialize(stripslashes($nav['href']));
        $default_app = strtolower(C("DEFAULT_MODULE"));
        $href = strtolower(leuu($href['action'], $href['param']));
        $g = C("VAR_MODULE");
        $href = preg_replace("/\/$default_app\//", "/", $href);
        $href = preg_replace("/$g=$default_app&/", "", $href);
    } else {
        if ($hrefold == "home") {
            $href = __ROOT__ . "/";
        } else {
            $href = $hrefold;
        }
    }
    $nav['href'] = $href;
    return $nav;
}

/**
 * 判断当前的语言包，并返回语言包名
 */
function sp_check_lang()
{
    $langSet = C('DEFAULT_LANG');
    if (C('LANG_SWITCH_ON', null, false)) {

        $varLang = C('VAR_LANGUAGE', null, 'l');
        $langList = C('LANG_LIST', null, 'zh-cn');
        // 启用了语言包功能
        // 根据是否启用自动侦测设置获取语言选择
        if (C('LANG_AUTO_DETECT', null, true)) {
            if (isset($_GET[$varLang])) {
                $langSet = $_GET[$varLang];// url中设置了语言变量
                cookie('think_language', $langSet, 3600);
            } elseif (cookie('think_language')) {// 获取上次用户的选择
                $langSet = cookie('think_language');
            } elseif (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {// 自动侦测浏览器语言
                preg_match('/^([a-z\d\-]+)/i', $_SERVER['HTTP_ACCEPT_LANGUAGE'], $matches);
                $langSet = $matches[1];
                cookie('think_language', $langSet, 3600);
            }
            if (false === stripos($langList, $langSet)) { // 非法语言参数
                $langSet = C('DEFAULT_LANG');
            }
        }
    }

    return strtolower($langSet);

}

/**
 * 删除图片物理路径
 * @param array $imglist 图片路径
 * @return bool 是否删除图片
 * @author 高钦 <395936482@qq.com>
 */
function sp_delete_physics_img($imglist)
{
    $file_path = C("UPLOADPATH");

    if ($imglist) {
        if ($imglist['thumb']) {
            $file_path = $file_path . $imglist['thumb'];
            if (file_exists($file_path)) {
                $result = @unlink($file_path);
                if ($result == false) {
                    $res = TRUE;
                } else {
                    $res = FALSE;
                }
            } else {
                $res = FALSE;
            }
        }

        if ($imglist['photo']) {
            foreach ($imglist['photo'] as $key => $value) {
                $file_path = C("UPLOADPATH");
                $file_path_url = $file_path . $value['url'];
                if (file_exists($file_path_url)) {
                    $result = @unlink($file_path_url);
                    if ($result == false) {
                        $res = TRUE;
                    } else {
                        $res = FALSE;
                    }
                } else {
                    $res = FALSE;
                }
            }
        }
    } else {
        $res = FALSE;
    }

    return $res;
}

/**
 * 返回结果统一格式；
 */
function RET($retCode, $retDesc, $retValue = '')
{
    header("Content-Type:text/html; charset=utf-8");

    //echo $retCode;
    $result = array('retCode' => $retCode, 'retDesc' => $retDesc, 'retValue' => $retValue);

    return echov(json_encode($result, 0));
}

/**
 * @param $retCode 状态码
 * @param $retDesc  描述
 * @return string   JSON字符串
 * 返回无值得JSON格式
 */
function RET_NO_V($retCode, $retDesc)
{
    header("Content-Type:text/html; charset=utf-8");
    $result = array('retCode' => $retCode, 'retDesc' => $retDesc);
    return echov(json_encode($result, 0));
}


function echov($vars)
{
    echo $vars;
}

/**
 * 封装三级分销方法
 * @uid int 用户ID 查上面的三级
 *
 *  返回值：
 * array(2) {
 * ["level1"] => array(2) {
 * ["person_id"] => string(1) "7"
 * ["person_type"] => string(1) "2"
 * }
 * ["level2"] => array(2) {
 * ["person_id"] => string(1) "8"
 * ["person_type"] => string(1) "1"
 * }
 * }
 */

function distribution($uid, $utype, $leval = 1)
{
    $app_distribution = M("recommend");

    //声明结果空数组
    static $result = array();
    //获取自已的父用户ID
    if ($leval <= 3) {
        $ret = $app_distribution->where(array('recommended_person_id' => $uid, 'recommended_person_type' => $utype))->field('recom_person_id,recom_person_type')->find();

        if ($ret) {
            $result['level' . $leval]['person_id'] = $ret['recom_person_id'];
            $result['level' . $leval]['person_type'] = $ret['recom_person_type'];
            $leval++;
            distribution($ret['recom_person_id'], $ret['recom_person_type'], $leval);
        }
    }
    return $result;
}

/**
 * 根据用户ID获取用户昵称
 * @param $uid 用户ID
 * @$utype 用户类型1：普通用户2跑客
 * @return mixed
 *
 */
function getUserNameForType($uid, $utype)
{
    $ret = null;
    if ($utype == 1) {
        $app_users = M("app_users");
        $ret = $app_users->where(array('user_id' => $uid))->field('user_name')->find();
    }
    if ($utype == 2) {
        $app_users = M("dispatch");
        $ret = $app_users->where(array('dispatch_id' => $uid))->field('dispatch_name as user_name')->find();
    }
    return $ret['user_name'];
}
/**
 * 根据用户ID获取 跑腿收入
 * @param $uid 用户ID
 * @return mixed
 *
 */
function getDispatchIncome($order_id, $did)
{
    $ret = null;

    $app_users = M("dispatch_balance");
    $ret = $app_users->where('dispatch_id=' . $did . ' and order_id = ' . $order_id . ' and balance_type=1')->field('balance_amount')->find();

    return $ret['balance_amount'] ? $ret['balance_amount'] : 0;
}

/**
 * 推荐用户订单奖励--三级分销211奖励
 * 订单分成(已完成的订单，并且没有分成，则执行该方法)
 * 跑客推荐普通用户:只有订单提成，没有激活分成
 * 用户推荐用户：只有订单提成，没有激活分成
 * @recom_id :订单用户id，
 * @order_id:订单id
 *
 * @return
 * 0:插入失败
 * 1：插入成功
 * 2:订单用户id 是空的
 * 3：订单id 是空的
 * 5：订单用户id、跑客id，订单id  非法
 *
 *
 * income_type=1:平台除去跑腿费后，应该的收入（包含了要分成的金额）
 * income_type=2：平台的真实收入
 *
 * --平台营业收入2.8 ----平台实际收入 2.8/2=1.4
 *                   ----推荐人分成
 *                   ----未分成完的，进入平台实际收入
 * 0:数据库插入修改操作失败，1：数据库插入修改操作成功，2，参数为空，3，没有需要分成的人
 *
 * 接口中判断：0：事务回滚，1,2,3不需要事务回滚
 */
function recommend_order_reward($user_id, $dispatch_id, $order_id,$order_money)
{

    if (!$user_id || !$dispatch_id||!$order_id)
        return 2;

    $order_db = M('order');
    $orderObj = $order_db->field('order_id,pay_method')
                        ->where(' order_id = ' . $order_id . ' and user_id = ' . $user_id . ' and dispatch_id = ' . $dispatch_id . ' and is_separate = 0 and status=7')
                        ->find();
    if (!$orderObj)
        return 3;

    $dispa_Income_per = getPnIncomeForDispatchId($dispatch_id);//跑客佣金比例
    $platform_total_income = round($order_money * $dispa_Income_per * 0.01,2);//平台总收入（佣金）
    $platform_data = array(
        'uid' => $user_id,
        'dispatch_id' => $dispatch_id,
        'ordermoney' => $order_money,
        'total_income' => $platform_total_income,
        'time' => date('Y-m-d H-i-s', time()),
        'orderid' => $order_id,
        'income_type' => 1
    );

    $systurnover_db = M('systurnover');
    $systurnover_ret = $systurnover_db->add($platform_data);

    if (!$systurnover_ret)
        return 0;

    //钱包支付，不参与分成，将佣金计入平台收入
    if($orderObj['pay_method'] == 3){
        $up_ret = $systurnover_db->where(array('id'=>$systurnover_ret))->setField(array('separate_income'=>$platform_total_income));
        if($up_ret)
            return 1;
        else
            return 0;
    }

//dump('平台收入：'.$platform_total_income);
    $level_user = distribution($user_id, '1');

    if ($level_user) {
        //dump('recom is not null');
        $per = 0.2;
        $dispatch_obj = M('dispatch')->field('company_id')->where(array('dispatch_id'=>$dispatch_id))->find();
        if($dispatch_obj['company_id']==3)
            $per = 0.08;
        $st_money = round($platform_total_income * $per,2);//要分的金额（参与分成的金额）
        $platform_yf = round($platform_total_income * (1-$per),2);//平台应得的除去分成后的余额
        $ymoney = 0; //参与分成金额中的已分的金额
        $count = 1;//用户类型是1，用户前N单分成，大于N单，则分成存入平台营业收入表
        $separate_n = 0;//用户前N
        foreach ($level_user as $key => $value) {

            if ($count > 3)
                break;

                //一级  50%
                if (strstr($key, '1'))
                    $money = round($st_money * 0.5,2);
                //二级  30%
                if (strstr($key, '2'))
                    $money = round($st_money * 0.3,2);
                //三级  20%
                if (strstr($key, '3'))
                    $money = $st_money - $ymoney;

                $ymoney += $money;//计算已分的金额


            //存入用户钱包表
            if ($value['person_type'] == 1) {
                $data = array(
                    'purse_type' => 6,
                    'user_id' => $value['person_id'],
                    'purse_amount' => $money,
                    'change_time' => date('Y-m-d H-i-s', time()),
                    'change_remark' => '推荐用户订单的分成金额',
                    'order_id' => $order_id,
                    'sum_amount'=>get_user_balance($value['person_id'])+$money
                );
                //dump('user_purse:');
                //dump($data);
                $user_purse_db = M('user_purse');
                $ret_add = $user_purse_db->add($data);

                if (!$ret_add)
                    return 0;
                $ub_ret = update_user_dispatch_blance($value['person_id'], 1, $money);

                if(!$ub_ret)
                    return 0;
                $ur_ret = updateRecommendPersonAmount($value['person_id'], 1, $money);

                if(!$ur_ret)
                    return 0;
                $msg_ret = create_user_message($value['person_id'],'推荐持续获利',"推荐持续获利",'恭喜您，您推荐用户持续获利金额'.number_format($money,2).'元');

                if(!$msg_ret)
                    return 0;
//                dump('推荐人'.$value['person_id'].'（用户）持续分成：'.$money);
            }
            //存入跑客余额表
            if ($value['person_type'] == 2) {
                $data = array(
                    'balance_type' => 5,
                    'dispatch_id' => $value['person_id'],
                    'balance_amount' => $money,
                    'time' => date('Y-m-d H-i-s', time()),
                    'change_memo' => '推荐用户订单的分成金额',
                    'order_id' => $order_id,
                    'sum_amount'=>get_dispatch_balance($value['person_id'])+$money
                );
                //dump('dispatch_balance:' . $count);
                //dump($data);
                $dispatch_balance_db = M('dispatch_balance');

                $ret_add = $dispatch_balance_db->add($data);

                if (!$ret_add)
                    return 0;
                $ub_ret = update_user_dispatch_blance($value['person_id'], 2, $money);

                if(!$ub_ret)
                    return 0;

                $ur_ret = updateRecommendPersonAmount($value['person_id'], 2, $money);

                if(!$ur_ret)
                    return 0;
                $msg_ret = create_dispatch_message($value['person_id'],'推荐持续获利',"推荐持续获利",'恭喜您，您推荐用户持续获利金额'.number_format($money,2).'元');

                if(!$msg_ret)
                    return 0;
//                dump('推荐人（跑客）'.$value['person_id'].'持续分成：'.$money);
            }
            $count++;
        }
//        dump('z:st_money = '.$st_money);
//        dump('z:ymoney = '.$ymoney);
        //已分的金额， 小于  要分的金额，金额存入平台营业收入
        if ($ymoney < $st_money) {
            $wmoney = $st_money - $ymoney;//0.36 - 0.18 = 0.18   分成后的剩余金额
            $wmoney = $wmoney + $platform_yf;// $platform_yf 平台应得的余额=（普通的跑客的佣金的80%或者直属跑客的佣金的92%）+ 分成剩余金额
        } else
            $wmoney = $platform_yf;// $platform_yf 平台应得的余额： 普通的跑客=佣金的80%，直属跑客=佣金的92%

        $up_ret = $systurnover_db->where('id='.$systurnover_ret)->setField('separate_income',$wmoney);//将平台的实际收入金额，存入数据库
//            dump('推荐人持续分成后，平台分成收入'.$wmoney);
            if(!$up_ret)
                return 0;
    } else {//无推荐人
        $up_ret = $systurnover_db->where('id='.$systurnover_ret)->setField('separate_income',$platform_total_income);
//        dump('无推荐人平台分成：'.$platform_total_income);
        if(!$up_ret)
            return 0;
    }

    $ret_update = $order_db->where('order_id=' . $order_id)->setField('is_separate', '1');
    if ($ret_update)
        return 1;
    else
        return 0;
}

/**
 * 跑单跑客的推荐人，奖励订单金额的2%
 * @param $user_id
 * @param $dispatch_id
 * @param $order_id
 * @param $order_money
 * @return int
 */
function recommend_robpn_reward($user_id, $dispatch_id, $order_id,$order_money)
{

    if (!$user_id || !$dispatch_id||!$order_id)
        return 2;

    $order_db = M('order');
    $orderObj = $order_db->field('order_id,pay_method')
        ->where(' order_id = ' . $order_id . ' and user_id = ' . $user_id . ' and dispatch_id = ' . $dispatch_id . ' and is_separate = 0 and status=7')
        ->find();
//    dump($orderObj);

    if (!$orderObj)
        return 3;

    $dispa_Income_per = getPnIncomeForDispatchId($dispatch_id);//跑客佣金比例
    $platform_total_income = round($order_money * $dispa_Income_per * 0.01,2);//平台总收入（佣金）
    //===========新增平台收入记录  start cln2017.02.10=======
    $platform_data = array(
        'uid' => $user_id,
        'dispatch_id' => $dispatch_id,
        'ordermoney' => $order_money,
        'total_income' => $platform_total_income,
        'time' => date('Y-m-d H-i-s', time()),
        'orderid' => $order_id,
        'income_type' => 1
    );
//    dump($platform_data);

    $systurnover_db = M('systurnover');
    $systurnover_ret = $systurnover_db->add($platform_data);
    //=========新增平台收入记录 end ============
    if (!$systurnover_ret)
        return 0;

    //钱包支付，不参与分成，将佣金计入平台收入
    if($orderObj['pay_method'] == 3){
        $up_ret = $systurnover_db->where(array('id'=>$systurnover_ret))->setField(array('separate_income'=>$platform_total_income));
        if($up_ret)
            return 1;
        else
            return 0;
    }

    $app_distribution = M("recommend");
    $ret = $app_distribution->where(array('recommended_person_id' => $dispatch_id, 'recommended_person_type' => 2))->find();
//    dump($ret);

    if (!$ret) {//没有推荐人
        $up_ret = $systurnover_db->where('id='.$systurnover_ret)->setField('separate_income',$platform_total_income);
//        dump('无推荐人平台分成：'.$platform_total_income);
        if(!$up_ret)
            return 0;
        return 2;
    }
    $per = 0.02;//奖励2%
    $reward_amount = round( $order_money * $per,2);//按订单金额比例奖励
//    dump('奖金：');
//    dump($reward_amount);
//    dump($ret['recom_person_type']);
    if($ret['recom_person_type']==1){
        $data = array(
            'purse_type' => 6,
            'user_id' => $ret['recom_person_id'],
            'purse_amount' => $reward_amount,
            'change_time' => date('Y-m-d H-i-s', time()),
            'change_remark' => '推荐跑客跑单的奖金',
            'order_id' => $order_id,
            'sum_amount'=>get_user_balance($ret['recom_person_id'])+$reward_amount
        );
//        dump('user_purse:');
//        dump($data);
        $user_purse_db = M('user_purse');
        $ret_add = $user_purse_db->add($data);//推荐人新增一条钱包明细

        if (!$ret_add)
            return 0;
        $ub_ret = update_recommend_blance($ret['recom_person_id'], 1, $reward_amount);// 修改 推荐人的 余额
        if (!$ub_ret)
            return 0;
        $msg_ret = create_user_message($ret['recom_person_id'],'推荐持续获利',"推荐持续获利",'恭喜您，您推荐的跑客跑单的持续获利金额'.number_format($reward_amount,2).'元');

        if(!$msg_ret)
            return 0;

    }elseif ($ret['recom_person_type']==2){
        $data = array(
            'balance_type' => 5,
            'dispatch_id' => $ret['recom_person_id'],
            'balance_amount' => $reward_amount,
            'time' => date('Y-m-d H-i-s', time()),
            'change_memo' => '推荐跑客跑单的奖金',
            'order_id' => $order_id,
            'sum_amount'=>get_dispatch_balance($ret['recom_person_id'])+$reward_amount
        );
//        dump('dispatch_balance:' . $reward_amount);
//        dump($data);

        $dispatch_balance_db = M('dispatch_balance');
        $ret_add = $dispatch_balance_db->add($data);//推荐人新增一条钱包明细

        if (!$ret_add)
            return 0;
        $ub_ret = update_recommend_blance($ret['recom_person_id'], 2, $reward_amount);// 修改 推荐人的 余额
        if (!$ub_ret)
            return 0;
        $msg_ret = create_dispatch_message($ret['recom_person_id'],'推荐持续获利',"推荐持续获利",'恭喜您，您推荐的跑客跑单的持续获利金额'.number_format($reward_amount,2).'元');

        if(!$msg_ret)
            return 0;
    }
    $up_ret = $systurnover_db->where('id='.$systurnover_ret)->setField('separate_income',$platform_total_income-$reward_amount);//将平台的实际收入金额，存入数据库
//            dump('推荐人持续分成后，平台分成收入'.$wmoney);
    if(!$up_ret)
        return 0;
    $ret_update = $order_db->where('order_id=' . $order_id)->setField('is_separate', '1');//将订单的是否分成字段设为  已分成
    if ($ret_update)
        return 1;
    else
        return 0;
}
/**
 * 修改余额和推荐奖励金额
 *
 * @param $id 用户id或跑客id
 * @param $utype 1：用户，2：跑客
 * @param $money 新增的金额
 * @return int  0：失败，1：成功，2，参数为空
 * 0：事务回滚，1不需要事务回滚
 */
function update_recommend_blance($id, $utype, $money)
{
    if (!$id || !$utype || !$money)
        return 2;
//    dump($id);
//    dump($utype);
//    dump('用户表保险金：'.$money);
    if ($utype == 1) {//用户表，用于余额字段
        $user_db = M('app_users');
        $user_purse = $user_db->where(' user_id = ' . $id)->field('purse_balance,recommend_amount')->find();
        $balance = $user_purse['purse_balance'];
        $ret_balance = $balance + $money;
        $recommen_count = floatval($user_purse['recommend_amount']) + $money;//推荐人分成金额
//        dump($ret_balance);
        $ret = $user_db->where('user_id=' . $id)->setField(array('purse_balance'=>$ret_balance,'recommend_amount'=>$recommen_count));
        if ($ret)
            return 1;
        else
            return 0;
    }
    if ($utype == 2) {//跑客表，跑客余额字段
        $user_db = M('dispatch');
        $user_purse = $user_db->where(' dispatch_id = ' . $id)->field('cash_balance,recommend_amount')->find();
        $balance = $user_purse['cash_balance'];
        $ret_balance = $balance + $money;
        $recommen_count = floatval($user_purse['recommend_amount']) + $money;//推荐人分成金额
//        dump('balance = '.$balance);
//        dump('ret_balance = '.$ret_balance);
        $ret = $user_db->where('dispatch_id=' . $id)->setField(array('cash_balance'=> $ret_balance,'recommend_amount'=>$recommen_count));
        if ($ret)
            return 1;
        else
            return 0;
    }
}
/**
 * 增加 用户表或跑客表的 余额字段  的值
 *
 * @param $id 用户id或跑客id
 * @param $utype 1：用户，2：跑客
 * @param $money 新增的金额
 * @return int  0：失败，1：成功，2，参数为空
 * 0：事务回滚，1不需要事务回滚
 */
function update_user_dispatch_blance($id, $utype, $money)
{
    if (!$id || !$utype || !$money)
        return 2;
//    dump($id);
//    dump($utype);
//    dump('用户表保险金：'.$money);
    if ($utype == 1) {//用户表，用于余额字段
        $user_db = M('app_users');
        $user_purse = $user_db->where(' user_id = ' . $id)->field('purse_balance')->find();
        $balance = $user_purse['purse_balance'];
        $ret_balance = $balance + $money;
//        dump($ret_balance);
        $ret = $user_db->where('user_id=' . $id)->setField('purse_balance', $ret_balance);
        if ($ret)
            return 1;
        else
            return 0;
    }
    if ($utype == 2) {//跑客表，跑客余额字段
        $user_db = M('dispatch');
        $user_purse = $user_db->where(' dispatch_id = ' . $id)->field('cash_balance')->find();
        $balance = $user_purse['cash_balance'];
        $ret_balance = $balance + $money;
//        dump('balance = '.$balance);
//        dump('ret_balance = '.$ret_balance);
        $ret = $user_db->where('dispatch_id=' . $id)->setField('cash_balance', $ret_balance);
        if ($ret)
            return 1;
        else
            return 0;
    }
}

/**
 * @package 推荐跑客激活奖励（推荐奖励分两种，订单提成，激活分成）
 * 跑客推荐跑客，用户推荐不奖励
 * 接一单奖励推荐人5元，跑5单奖励推荐人10元，跑9单奖励推荐人15
 * @dispatch_id :订单跑客id(作为被推荐人)
 *
 * @return 0:数据库插入修改操作失败，1：数据库插入修改操作成功，2，没有需要分成的人
 *
 * 接口中判断：0：事务回滚，1,2不需要事务回滚
 */
function recommend_active_reward($dispatch_id,$order_id)
{
    //查推荐表，确定推荐人，是用户还是跑客
    //如果推荐人是跑客，则在派单员余额明细中增加一条明细，在派单员表中更改现金余额
    //增加的金额，在文件中获取

    if (!$dispatch_id||!$order_id) {
        return 2;//参数不合法
    }
    $dispatch_obj =M('dispatch')->where(array('dispatch_id'=>$dispatch_id))->find();
    //该跑客已经完成的订单数
    $finish_order_count = $dispatch_obj['comp_order_num'];
//    dump('推荐的跑客'.$dispatch_id.'历史完成订单记录数='.$finish_order_count);

    if($finish_order_count !=0 && $finish_order_count !=4 && $finish_order_count != 8 )
        return 2;

    $order_count = $finish_order_count + 1 ;

    $app_distribution = M("recommend");
    $ret = $app_distribution->where(array('recommended_person_id' => $dispatch_id, 'recommended_person_type' => 2))->find();

    if (!$ret) {
        return 2;//没有推荐人
    }
    $recom_amount = 0.00;//奖励金额 0
    //推荐人是跑客,且被推荐人跑了一单
    if($order_count == 1 )
        $recom_amount = 5.00;//奖励金额 5

    if($order_count == 5 )
        $recom_amount = 10.00;//奖励金额 10
    if($order_count == 9 )
        $recom_amount = 15.00;//奖励金额 15

    if($recom_amount==0.00)
        return 2;
//    dump('有推荐人，需要推荐奖励金额'.$recom_amount);

    if($ret['recom_person_type']==1){
//        dump('有推荐人是用户');
        //dispatch_balance新增 资金记录
        $data = array(
            'purse_type' => 6,
            'user_id' => $ret['recom_person_id'],
            'purse_amount' => $recom_amount,
            'change_time' => date('Y-m-d H-i-s', time()),
            'change_remark' => '您推荐的跑客成功完成'.$order_count.'单，奖励' . number_format($recom_amount) . '元',
            'order_id' => $order_id,
            'sum_amount'=>get_user_balance($ret['recom_person_id'])+$recom_amount
        );

        $user_purse_db = M('user_purse');
        $ret_add = $user_purse_db->add($data);

        if (!$ret_add)
            return 0;
        $user_db = M('app_users');
        $user_purse = $user_db->where(' user_id = ' . $ret['recom_person_id'])->field('purse_balance,recommend_amount')->find();
        $user_data['purse_balance'] = $user_purse['purse_balance'] + $recom_amount;
        $user_data['recommend_amount']=$user_purse['recommend_amount'] + $recom_amount;//激活奖励金额
        $user_data['user_id'] = $ret['recom_person_id'];
        $users_ret = $user_db->where(array('user_id'=>$ret['recom_person_id']))->save($user_data);

        $msg_ret = create_user_message($ret['recom_person_id'],'推荐奖励',"推荐奖励",'恭喜您，您推荐的跑客成功完成'.$order_count.'单，奖励' . number_format($recom_amount, 2) . '元');

        if ($users_ret && $msg_ret)
            return 1;//推荐奖励成功
         else
            return 0;//修改失败

    }elseif ($ret['recom_person_type']==2){
//        dump('有推荐人是跑客');
        //dispatch_balance新增 资金记录
        $change_memo = '您推荐的跑客成功完成'.$order_count.'单，奖励' . number_format($recom_amount,2) . '元';
        $add_status = pnOrderDetail($ret['recom_person_id'], $recom_amount, 5, $change_memo, $order_id, '推荐奖励');
        //dispatch修改余额
        if ($add_status) {
            $dispatch_db = M('dispatch');
            $dispatch_obj = $dispatch_db->where('dispatch_id=' . $ret['recom_person_id'])->field('cash_balance,recommend_amount')->find();
            $dispatch_data['cash_balance'] = $dispatch_obj['cash_balance'] + $recom_amount;
            $dispatch_data['recommend_amount']=$dispatch_obj['recommend_amount'] + $recom_amount;//激活奖励金额
            $dispatch_data['dispatch_id'] = $ret['recom_person_id'];
            $save_status = $dispatch_db->where(array('dispatch_id'=>$ret['recom_person_id']))->save($dispatch_data); // 根据条件更新记录
            $msg_ret = create_dispatch_message($ret['recom_person_id'],'推荐奖励',"推荐奖励",'恭喜您，'.$change_memo);

            if ($save_status && $msg_ret)
                return 1;//推荐奖励成功
            else
                return 0;//修改失败
        } else
            return 0;//新增失败
        
    }
}

/**
 * 当被推荐人激活时，修改推荐人的推荐人数
 * @param $uid 用户或跑客id
 * @param $utype 用户类型 1：普通用户，2：跑客
 * @return 0:修改失败，1：成功
 * 0：事务回滚，1事务不回滚
 */
function updateRecommendPersonCount($uid,$utype){
    if(!$uid || !$utype){
        return 0;
    }
    if ($utype == 1) {//用户表，用于余额字段
        $user_db = M('app_users');
        $user_purse = $user_db->where(' user_id = ' . $uid)->field('recommend_person_count')->find();
        $recommen_count = intval($user_purse['recommend_person_count']) + 1;//推荐人分成金额
//        dump($ret_balance);
        $ret = $user_db->where('user_id=' . $uid)->setField(array('recommend_person_count'=>$recommen_count));
        if ($ret)
            return 1;
        else
            return 0;
    }
    if ($utype == 2) {//跑客表，跑客余额字段
        $user_db = M('dispatch');
        $user_purse = $user_db->where(' dispatch_id = ' . $uid)->field('recommend_person_count')->find();
        $recommen_count = intval($user_purse['recommend_person_count']) + 1;//被推荐人数量加1

        $ret = $user_db->where('dispatch_id=' . $uid)->setField(array('recommend_person_count'=>$recommen_count));
//        dump($user_db->getLastSql());
        if ($ret){
            return 1;
        }else{

            return 0;
        }
    }
}

/**
 * 当被推荐用户有推荐人时，其订单金额要参与平台、推荐人分成
 * @param $uid 用户或跑客id
 * @param $utype 用户类型：1用户，2：跑客
 * @param $amount 分成金额
 * @return int
 */
function updateRecommendPersonAmount($uid,$utype,$amount){
    if(!$uid || !$utype){
        return 0;
    }

    if ($utype == 1) {//用户表，用于余额字段
        $user_db = M('app_users');
        $user_purse = $user_db->where(' user_id = ' . $uid)->field('recommend_amount')->find();
        $recommen_count = floatval($user_purse['recommend_amount']) + $amount;//推荐人分成金额
//        dump($ret_balance);
        $ret = $user_db->where('user_id=' . $uid)->setField(array('recommend_amount'=>$recommen_count));
        if ($ret)
            return 1;
        else
            return 0;
    }
    if ($utype == 2) {//跑客表，跑客余额字段
        $user_db = M('dispatch');
        $user_purse = $user_db->where(' dispatch_id = ' . $uid)->field('recommend_amount')->find();
        $recommen_count = floatval($user_purse['recommend_amount']) + $amount;//推荐人的分成金额
        $ret = $user_db->where('dispatch_id=' . $uid)->setField(array('recommend_amount'=>$recommen_count));

//        dump($user_db->getLastSql());
        if ($ret){
            return 1;
        }else{

            return 0;
        }
    }
}
/**
 * @package 根据跑客id获取跑客的手机号
 * @param $dis_id :跑客id
 */
function get_dispatch_mobile($dis_id)
{

    if (!$dis_id) {
        return 0;
    }
    $dispatch_db = M('dispatch');
    $mobile = $dispatch_db->field('mobile')->where(array('dispatch_id' => $dis_id))->find();
    //dump($mobile);
    return $mobile['mobile'];
}


/**
 * @package 跑客级别处理
 * @param $expValue 经验值
 * @param $dispatch_id 跑客ID
 */
function pnLevel($expValue, $dispatch_id)
{
    $dispatch = M('dispatch');
    $ret = $dispatch->where(array('dispatch_id' => $dispatch_id))->field('company_id,growth_value,dispatch_level_id')->find();

    if ($ret && $ret['company_id'] != 3 ) {
        $value = $ret['growth_value'] + $expValue;
        $dispatch_level_id = $ret['dispatch_level_id'];
        $dispatch_level = M('dispatch_level');
        $lowest_growth_value = $dispatch_level->field('lowest_growth_value')->select();
        if ($lowest_growth_value) {
            for ($i = 0; $i < count($lowest_growth_value); $i++) {
                if ($value < $lowest_growth_value[$i]['lowest_growth_value']) {
                    $ret = $dispatch_level->where(array('lowest_growth_value' => $lowest_growth_value[$i]['lowest_growth_value']))->field('dispatch_level_id')->find();
                    $dispatch_level_id = $ret['dispatch_level_id'];
                    break;
                }
            }
            $ret = $dispatch->where(array('dispatch_id' => $dispatch_id))->save(array('growth_value' => $value, 'dispatch_level_id' => $dispatch_level_id));
            //跑客经验值纪录
            pnLevelLog($expValue, $dispatch_id, "完成订单奖励");
            if ($ret) {
                return true;
            } else {
                return false;
            }
        } else {
            return false;
        }
    } else {
        return true;
    }
}

//跑客经验值纪录
function pnLevelLog($expValue, $dispatch_id, $remank = "")
{
    $dispatch_exp = M('dispatch_exp');
    $ret = $dispatch_exp->add(array(
        'expvalue' => $expValue,
        'dispatch_id' => $dispatch_id,
        'time' => date('Y-m-d H:i:s'),
        'info' => $remank
    ));
    if ($ret) {
        return true;
    } else {
        return false;
    }
}

/**
 * @package 用户级别处理
 * @param $expValue 经验值
 * @param $user_id 用户ID
 */
function user_level($expValue, $user_id)
{
    $app_users = M('app_users');
    $ret = $app_users->where(array('user_id' => $user_id))->field('growth_value,user_level_id')->find();
    if ($ret) {
        $value = $ret['growth_value'] + $expValue;
        $user_level_id = $ret['user_level_id'];
        $user_level = M('user_level');
        $lowest_growth_value = $user_level->field('lowest_growth_value')->select();
        if ($lowest_growth_value) {
            for ($i = 0; $i < count($lowest_growth_value); $i++) {
                if ($value < $lowest_growth_value[$i]['lowest_growth_value']) {
                    $ret = $user_level->where(array('lowest_growth_value' => $lowest_growth_value[$i]['lowest_growth_value']))->field('user_level_id')->find();
                    $user_level_id = $ret['user_level_id'];
                    break;
                }
            }
            $ret = $app_users->where(array('user_id' => $user_id))->save(array('growth_value' => $value, 'user_level_id' => $user_level_id));
            userLevelLog($user_id, $expValue, "完成订单奖励");
            if ($ret) {
                return true;
            } else {
                return false;
            }
        } else {
            return false;
        }
    } else {
        return false;
    }
}

//用户经验记录表
function userLevelLog($uid, $expvalue, $remank = "")
{
    $data = array(
        'uid' => $uid,
        'expvalue' => $expvalue,
        'time' => date('Y-m-d H:i:s'),
        'info' => $remank,
    );
    $ret = M('user_explog')->add($data);
    if ($ret) {
        return true;
    } else {
        return false;
    }
}

/**
 * @package 跑客好评处理
 * @param $ratedValue 此次评价的星星数
 * @param $dispatch_id 跑客ID
 */
function pnPraise($ratedValue, $dispatch_id)
{
    $dispatch = M('dispatch');
    $ret = $dispatch->where(array('dispatch_id' => $dispatch_id))->field('evaluate_count,evaluate_star')->find();
    if ($ret) {
        //数据库之后的好评星星数
        $nowStar = $ret['evaluate_star'];
        //好评的数量
        $evaluate_count = $ret['evaluate_count'];
        //计算目前的星星数
        $nowStar = $nowStar + $ratedValue;
        //计算目前评价的数量
        $evaluate_count = $evaluate_count+1;
        $nowPraise = (($nowStar) / ($evaluate_count * 5)) * 100;

//        if($ratedValue>=4){
//            $nowStar = $ret['evaluate_star'] + $ratedValue;
//            $evaluate_count++;
//        }else if($ratedValue == 0){
//            return false;
//        }
//
//        $nowPraise = (($nowStar) / ($evaluate_count * 5)) * 100;

        $dispatch->where(array('dispatch_id' => $dispatch_id))->save(array('evaluate_count'=>$evaluate_count,'evaluate_star' => $nowStar, 'praise' => $nowPraise));
        return true;
    } else {
        return false;
    }

}

/**
 * @package 跑客帮币处理 （需要做记录到db_coin_detail）
 * @param $coinValue 帮币值
 * @param $type 1 增加 2 扣除
 * @param $reason 帮币改变原因
 * @param $remark 帮币改变备注
 * @param $dispatch_id 跑客ID
 */
function pnCoin($coinValue, $type, $dispatch_id, $reason, $remark)
{
    $dispatch = M('dispatch');
    $ret = $dispatch->where(array('dispatch_id' => $dispatch_id))->field('coin_balance')->find();
    if ($ret) {
        $coin_balance = $ret['coin_balance'];
        $coin_detail = M('coin_detail');
        switch ($type) {
            case 1:
                $coin_balance += $coinValue;
                $data = array(
                    'dispatch_id' => $dispatch_id,
                    'amount' => $coinValue,
                    'reason' => $reason,
                    'remark' => $remark,
                    'get_time' => date('Y-m-d H:i:s')
                );
                $coin_detail->add($data);
                break;
            case 2:
                $coin_balance -= $coinValue;
                $data = array(
                    'dispatch_id' => $dispatch_id,
                    'amount' => $coinValue*-1,
                    'reason' => $reason,
                    'remark' => $remark,
                    'get_time' => date('Y-m-d H:i:s')
                );
                $coin_detail->add($data);
        }
        $ret = $dispatch->where(array('dispatch_id' => $dispatch_id))->save(array('coin_balance' => $coin_balance));
        if ($ret) {
            return true;
        } else {
            return false;
        }
    }else{
        return false;
    }
}

/**
 * @package 信用评分机制
 * @param $dispatch_id 跑客id
 * @param $score 信用值改变量
 * @param $type 类型( 1 增加 2 减少)
 * @param $reason 事由
 * @param $remark 备注
 * @return bool
 */
function pnCreditScore($dispatch_id, $score, $type, $reason, $remark)
{
    $dispatch = M('dispatch');
    $ret = $dispatch->where(array('dispatch_id' => $dispatch_id))->field('credit_points')->find();
    $credit_points = $ret['credit_points'];
    switch ($type) {
        case 1:
            if ($credit_points >= 12) {
                return true;
            } else {
                $credit_points += $score;
                if ($credit_points > 12) {
                    $ret = $dispatch->where(array('dispatch_id' => $dispatch_id))->save(array('credit_points' => 12));
                    if ($ret) {
                    } else {
                        return false;
                    }
                }
                break;
            }
        case 2:
            if ($credit_points <= 0) {
                return true;
            } else {
                $credit_points -= $score;
                if ($credit_points < 0) {
                    $ret = $dispatch->where(array('dispatch_id' => $dispatch_id))->save(array('credit_points' => 0, 'account_status' => 2));
                    if ($ret) {
                        return true;
                    } else {
                        return false;
                    }
                }
            }
    }
    $ret = $dispatch->where(array('dispatch_id' => $dispatch_id))->save(array('credit_points' => $credit_points));
    if ($ret) {
        $data = array(
            'dispatch_id' => $dispatch_id,
            'change_value' => $score,
            'reason' => $reason,
            'type' => $type,
            'remark' => $remark
        );
        $rets = M('redit_change')->add($data);
        if ($rets) {
            return TRUE;
        } else {
            return false;
        }
    }
}

/**
 * 取送订单计算---实际跑腿收入=订单金额*（1-佣金比值/100）
 * @param $order_id 订单id
 * @return bool
 */
function pnOrderAccount($order_id)
{
    $order = M('order');
    $dispatch = M('dispatch');
    $ret = $order->where(array('order_id' => $order_id,'status'=>7))->field('order_type,dispatch_id,order_amount,order_number,send_address,reci_address,is_have_price,goods_amount')->find();

    if ($ret) {
        $rets = $dispatch->where(array('dispatch_id' => $ret['dispatch_id']))->field('dispatch_level_id,cash_balance')->find();

        if ($rets) {
            $order_amount = $ret['order_amount'];
            $goods_amount = $ret['goods_amount'];
            $ret_amount = $order_amount;
            if(2 == $ret['order_type'] && $ret['is_have_price']==1)//知道价格
                $ret_amount = $order_amount-$goods_amount;
//            dump('参与跑腿费的金额='.$ret_amount);
            $dispatch_level = M('dispatch_level');
            $result = $dispatch_level->where(array('dispatch_level_id' => $rets['dispatch_level_id']))->field('serv_charge_rate')->find();
            $serv_charge_rate = $result['serv_charge_rate'];
            $balance_amount = round($ret_amount * (1 - $serv_charge_rate / 100),2);
            $cash_balance = $balance_amount + $rets['cash_balance'];

            $change_memo = '单号 ' . $ret['order_number'];
            $remark = '类型为'.getOrderTypeName($ret['order_type']).',单号为“' . $ret['order_number']. '”的跑腿收入' . $balance_amount.'元';
            $retsss = pnOrderDetail($ret['dispatch_id'], $balance_amount, 1, $change_memo, $order_id, $remark);

            if ($retsss) {
                $retss = $dispatch->where(array('dispatch_id' => $ret['dispatch_id']))->save(array('cash_balance' => $cash_balance));
                if ($retss) {
                    return true;
                }else
                    return false;
            } else
                return false;

        }else
            return false;
    } else {
        return false;
    }
}
/**
 * 获取实际跑腿收入=订单金额*（1-佣金比值/100）
 * @param $order_id 订单id
 * @return bool
 */
function get_pnOrderAccount($order_id,$new_dispatch_id=0)
{
    $order = M('order');
    $dispatch = M('dispatch');
    $ret = $order->where('order_id='.$order_id. ' and status >= 2 and status <= 6 ')->field('order_type,dispatch_id,order_amount,order_number,send_address,reci_address,is_have_price,goods_amount')->find();

    if ($ret) {
        if(!$new_dispatch_id || $new_dispatch_id == 0 )
            $new_dispatch_id = $ret['dispatch_id'];
        $rets = $dispatch->where(array('dispatch_id' => $new_dispatch_id))->field('dispatch_level_id,cash_balance')->find();

        if ($rets) {
            $order_amount = $ret['order_amount'];
            $goods_amount = $ret['goods_amount'];
            $ret_amount = $order_amount;
            if (2 == $ret['order_type'] && $ret['is_have_price'] == 1)//知道价格
                $ret_amount = $order_amount - $goods_amount;
//            dump('参与跑腿费的金额='.$ret_amount);
            $dispatch_level = M('dispatch_level');
            $result = $dispatch_level->where(array('dispatch_level_id' => $rets['dispatch_level_id']))->field('serv_charge_rate')->find();
            $serv_charge_rate = $result['serv_charge_rate'];
            $balance_amount = round($ret_amount * (1 - $serv_charge_rate / 100), 2);
            return $balance_amount;
        }else
            return 0.00;
    }else{
        return 0.00;
    }
}
/**
 * 跑客余额记录表
 * @param $dispatch_id 跑客id
 * @param $balance_amount 金额
 * @param $change_memo 变动说明
 * @param $type 类型:1、跑腿订单收入，2代购垫付入账，3帮币兑换收入，4提现支出，5推荐用户奖励',
 * @param $order_id 订单id
 * @param $remark 备注
 * @param cash_record_id 提款记录id 可以选填
 * @return bool
 */
function pnOrderDetail($dispatch_id, $balance_amount, $type, $change_memo, $order_id, $remark, $cash_record_id = 0)
{
    $dispatch_balance = M('dispatch_balance');

    if($type == 4 )
        $sum_amount = get_dispatch_balance($dispatch_id)-$balance_amount;
    else
        $sum_amount = get_dispatch_balance($dispatch_id)+$balance_amount;

    $data = array(
        'dispatch_id' => $dispatch_id,
        'balance_amount' => $balance_amount,
        'balance_type' => $type,
        'change_memo' => $change_memo,
        'time' => date('Y-m-d H:i:s'),
        'order_id' => $order_id,
        'remark' => $remark,
        'cash_record_id' => $cash_record_id,
        'sum_amount'=>$sum_amount
    );
    $ret = $dispatch_balance->add($data);
    if ($ret)
        return true;
    else
        return false;
}


/**
 * 根据跑客ID返回跑客的审核状态（字典）0 未提交审核 1已提交审核，2已经审核通过 3审核未通过)
 * @param $dispatch_id 跑客ID
 * @return 审核状态
 */
function getPnAudit($dispatch_id)
{
    $dispatch = M('dispatch');
    //反查出来跑客的审核状态is_audit
    $ret = $dispatch->where(array('dispatch_id' => $dispatch_id))->field('is_audit')->find();
    switch ($ret['is_audit']) {
        case 0:
            return "未提交审核";
            break;
        case 1:
            return "正在审核中";
            break;
        case 2:
            return "已经审核通过";
            break;
        case 3:
            return "审核未通过";
            break;
    }
}


/**
 * 根据跑客ID返回跑客级别
 */
function getPnLevel($dispatch_level_id)
{
    $dispatch_level = M('dispatch_level');
    $ret = $dispatch_level->where(array('dispatch_level_id' => $dispatch_level_id))->field('level_name')->find();
    return $ret['level_name'];


    array(
        "mileage" => array(                   //里程费
            array(
                "title" => "2公里",
                "kilometre" => 2,
                "money" => 8,
                "money_title" => "8.0元"
            ),
            array(
                "title" => "3公里",
                "kilometre" => 3,
                "money" => 12,
                "money_title" => "12.0元"
            )
        ),
        "line_up" => array(                  //排队费用

        ),
        "night" => array(                     //夜间补助

        ),
        "temporary" => array(                 //临时加价

        ),
        "is_starting_price" => array(         //起步价冗余字段
            "kilometre" => 3,
            "money" => 12,
        )
    );
}


/**
 * 根据跑客的层级返回跑客收入比例
 * @param $dispatch_level_id 跑客的级别ID
 * @return int 跑客收入比例
 */
function getPnIncome($dispatch_level_id)
{
    //实例化跑客的级别ID
    $dispatch_level = M('dispatch_level');
    //根据跑客的层级返回跑客收入比例
    $ret = $dispatch_level->where(array('dispatch_level_id' => $dispatch_level_id))->field('serv_charge_rate')->find();
    return $ret['serv_charge_rate'] * 0.1;
}


/**
 * 根据跑客ID返回跑客收入比例
 * @param $dispatch_id 跑客ID
 * @return int 跑客收入比例
 */
function getPnIncomeForDispatchId($dispatch_id)
{
    //实例化跑客表
    $dispatch_db = M('dispatch d');
    //查询此跑客的收入比例
    $ret = $dispatch_db->field('l.serv_charge_rate')
        ->where(array('d.dispatch_id' => $dispatch_id))
        ->join('db_dispatch_level l on d.dispatch_level_id = l.dispatch_level_id')
        ->find();
    return $ret['serv_charge_rate'];
}

/**
 * 计算某个经纬度的周围某段距离的正方形的四个点
 * @param lng float 经度
 * @param lat float 纬度
 * @param distance float 该点所在圆的半径，该圆与此正方形内切，默认值为1.5千米
 * @return array 正方形的四个点的经纬度坐标
 */
function returnSquarePoint($lng, $lat, $distance = 3)
{
    //计算四个点
    $dlng = 2 * asin(sin($distance / (2 * EARTH_RADIUS)) / cos(deg2rad($lat)));
    $dlng = rad2deg($dlng);
    $dlat = $distance / EARTH_RADIUS;
    $dlat = rad2deg($dlat);
    //正方形的四个点的经纬度坐标
    return array(
        'left-top' => array('lat' => $lat + $dlat, 'lng' => $lng - $dlng),
        'right-top' => array('lat' => $lat + $dlat, 'lng' => $lng + $dlng),
        'left-bottom' => array('lat' => $lat - $dlat, 'lng' => $lng - $dlng),
        'right-bottom' => array('lat' => $lat - $dlat, 'lng' => $lng + $dlng)
    );
}

/**
 * 判断金额赠送策略 （已验证）
 * 传递充值金额返回优惠的金额
 * @param $money 传入要充值的金额
 * @return int 送出的金额
 */
function give_money($money)
{
    //实例化用户充值优惠策略表
    $user_recharge_discount = M('user_recharge_discount');
    //查询出来相应的充值金额的优惠
    $recharge_discount_data = $user_recharge_discount->cache(true)->where(array('money' => $money))->field('give_money')->find();
    //返回优惠的金额给方法的调用者
    return $recharge_discount_data['give_money'];
}

/**
 *
 */
function order_model($status){
    //dump(C('order_model'));
}

/**
 * 订单金额计算
 * @param $cityId float 城市
 * @param $kilometers float 公里数
 */
function getMoney($cityId, $kilometers)
{
    $pricing_tactics = M('pricing_tactics');
    $kilometers = round($kilometers);
    $totalPrice = 0;
    $ret = $pricing_tactics->where(array('city_id' => $cityId))->field('tactics_array')->find();
    if ($ret['tactics_array']) {
        $tactics_array = json_decode($ret['tactics_array'], TRUE);
        //dump($tactics_array);
        $mileage = $tactics_array['mileage'];
        $starting_price = $tactics_array['is_starting_price'];
        //判断是否大于起步价
        if ($kilometers <= $starting_price['mileageKilometre']) {
            for ($i = 0; $i < count($mileage); $i++) {
                if ($kilometers <= $mileage[$i]['kilometre']) {
                    $totalPrice += $mileage[$i]['money'];
                    break;
                }
            }
        } else {
            for ($i = 0; $i < count($mileage); $i++) {
                if ($kilometers < $mileage[$i]['kilometre']) {
                    $totalPrice += $mileage[$i - 1]['money'];
                    $meter = $kilometers - $mileage[$i - 1]['kilometre'];
                    $totalPrice += $meter * $mileage[$i]['pricePer'];
                    break;
                }
            }
        }

    }
    return $totalPrice;
}
/**
 * 两个起步价的订单金额计算
 * @param $cityId float 城市
 * @param $kilometers float 公里数
 * 返回值；
 * @param "startkilometres"  起始公里数
 * @param startmoney" 起始金额
 * @param "totalPrice" 总里程金额
 * @param "money" 超起始价金额
 * @param"kilometres" 超起始公里数
 */
function getTwoStartKiloMoney($cityId, $kilometers)
{
    $pricing_tactics = M('pricing_tactics');
    $kilometers = round($kilometers);
//    dump('公里数：');
//    dump($kilometers);
    $totalPrice = array();
    $ret = $pricing_tactics->where(array('city_id' => $cityId))->field('tactics_array')->find();

    if ($ret['tactics_array']) {
        $tactics_array = json_decode($ret['tactics_array'], TRUE);
        $mileage = $tactics_array['mileage'];
        $starting_price = $tactics_array['is_starting_price'];

        //计算起步公里数及起步价
         foreach ($starting_price as $key => $value){//起步价集合循环
             if ($kilometers <= round($value['mileageKilometre']) || $key == count($starting_price)-1) {//起步价
                 $totalPrice['startkilometres'] = $value['mileageKilometre'];//起步公里数
                 $totalPrice['startmoney'] = $value['mileageMoney'];//起步价
                 $totalPrice['totalPrice'] = $value['mileageMoney'];
                 $totalPrice['money'] =0.00;
                 $totalPrice['kilometres'] = 0.00;
                 break;
             }
         }
//        dump('totalPrice：');
//        dump($totalPrice);
        //计算里程公里数及里程费用
        $mileage_kilometre = 0.00 ;
        $mileage_money = 0.00;
        foreach ($mileage as $key1 => $value1){//起步价集合循环
//            dump('循环'.$key1);
//            dump('kilometre = '. $kilometers);
//            dump('startkilometres = '.round($totalPrice['startkilometres']));
//            dump('value1-kilometre = '.round($value1['kilometre']));
            if ($kilometers > round($totalPrice['startkilometres'])&& $kilometers <= round($value1['kilometre'])) {//小于等于起步价，则里程费0，否则计算里程费
                $mileage_money += $mileage[$key1 - 1]['money'];
//                dump($mileage_money);
                $mileage_kilometre += $kilometers - $mileage[$key1 - 1]['kilometre'];
//                dump($mileage_kilometre);
                $mileage_money += $mileage_kilometre * $mileage[$key1]['pricePer'];
//                dump($mileage_money);
                break;
            }
        }
//        dump($mileage_kilometre);
//        dump($mileage_money);
        if($mileage_kilometre > 0 ){
            $totalPrice['totalPrice'] =$mileage_money;
            $totalPrice['money'] =$mileage_money-$totalPrice['startmoney'];
        }
    }
    return $totalPrice;
}

/**
 * 最终推送的数据（已验证、后台使用）
 * @param $push_data 推送的数据（json对象）
 */
function push_server_data($push_data)
{

    $str = "";
    $str .= '<!doctype html><html lang="en"><head><meta charset="UTF-8" />';
    $str .= '<title></title><script src="//cdn.bootcss.com/socket.io/1.2.0/socket.io.js"></script>';
    $str .= '<script>var socket = io(\'wss://122.114.90.191:8360\');socket.emit(\'adduser\',"sysadmin");socket.emit(\'chat\', JSON.stringify(' . $push_data . '));</script>';
    $str .= '</head><body><center>重新发单成功！</center></body></html>';
    echo $str;
}

/**
 * 支付宝退款
 * @param $order_number 订单号
 * @param $alipay_number 支付宝流水号
 * @param $money 退款金额
 * @param $refund_reason 退款理由
 * @return bool true成功，false失败
 * @throws Exception  异常
 */
function returnMoney($order_number, $alipay_number, $money, $refund_reason,$request_no='ccxxno')
{

    vendor("alipay_api.aop.AopClient");
    vendor("alipay_api.aop.request.AlipayTradeRefundRequest");

    $aop = new \AopClient ();
    $aop->gatewayUrl = 'https://openapi.alipay.com/gateway.do';
    $aop->appId = '2016042901347993';
    $aop->rsaPrivateKeyFilePath = SPAPP_PATH.'Core/Library/Vendor/alipay_api/aop/key/rsa_private_key.pem';
    $aop->alipayPublicKey = SPAPP_PATH.'Core/Library/Vendor/alipay_api/aop/key/alipay_public_key.pem';

    $aop->apiVersion = '1.0';
    $aop->postCharset = 'utf-8';
    $aop->format = 'json';
    $request = new \AlipayTradeRefundRequest ();

    $data = array(
        "out_trade_no" => $order_number, //订单号
        "trade_no" => $alipay_number, //支付宝流水号
        "refund_amount" => $money, //退款金额
        "refund_reason" => $refund_reason,// 退款理由  可选
        "out_request_no"=>$request_no
    );

    $bizContent = json_encode($data);

    $request->setBizContent($bizContent);

    $result = $aop->execute($request);

    $responseNode = str_replace(".", "_", $request->getApiMethodName()) . "_response";

    $resultCode = $result->$responseNode->code;

    if (!empty($resultCode) && $resultCode == 10000) {
        return true;
    } else {
        return false;
    }


}
/**
 * 微信退款
 * @param $order_number 订单号
 * @param $alipay_number 微信流水号
 * @param $money 退款金额
 * @return bool true成功，false失败
 * @throws Exception  异常
 */
function returnMoneyWeixin($order_number,$alipay_number, $pay_amount, $refund_fee, $user_id)
{
    vendor("WxpayAPI.WxPay");
    $input = new WxPayRefund();

    $input->SetTransaction_id($alipay_number);//微信生成的订单号，在支付通知中有返回
    $input->SetOut_trade_no($order_number);//商户传给微信的订单号
    $input->SetOut_refund_no($order_number.date("YmdHis"));//商户系统内部的退款单号，商户系统内部唯一，同一退款单号多次请求只退一笔
    $input->SetTotal_fee(round($pay_amount,2)*100);//订单总金额，单位为分，只能为整数
    $input->SetRefund_fee(round($refund_fee,2)*100);//退款总金额，订单总金额，单位为分，只能为整数
    $input->SetOp_user_id($user_id);//设置操作员帐号, 默认为商户号
    
    $result = WxPayApi::refund($input);

    if($result['result_code']=='SUCCESS')
        return true;
    else
        return false;
}

function printf_info($data)
{
    foreach($data as $key=>$value){
        echo "<font color='#f00;'>$key</font> : $value <br/>";
    }
}
function format_money($STR)
{
    //var_dump(is_int($STR));
    if ($STR == "") {
        return "0.00";
    }
    if ($STR == ".00") {
        return "0.00";
    }
    if(is_int($STR)){
        return $STR.".00";
    }

    $TOK = strtok($STR, ".");
    if (strcmp($STR, $TOK) == "0") {
        $STR .= ".00";
    } else {
        $TOK = strtok(".");
        $I = 1;
        for (; $I <= 2 - strlen($TOK); ++$I) {
            $STR .= "0";
        }
    }
    if (substr($STR, 0, 1) == ".") {
        $STR = "0" . $STR;
    }



    return $STR;
}

/**
 * 最终推送的数据（已验证、App端使用）
 * @param $push_data 推送的数据（json对象）
 */
function push_server_appdata($push_data)
{

    $str = "";
    $str .= '<script src="//cdn.bootcss.com/socket.io/1.2.0/socket.io.js"></script>';
    $str .= '<script>var socket = io(\'http://122.114.90.191:8360\');socket.emit(\'adduser\',"sysadmin");socket.emit(\'chat\', JSON.stringify(' . $push_data . '));</script>';

    echo $str;
}

///**
// * 每天跑客接第一单时，扣除保险费
// *
// * @param $dispatch_id 跑客id 必填
// * @param $order_id 订单id 必填
// * @param $insurance_amount 保险金额 必填
// * @return int 0插入数据出错，1：扣除保险费成功，2：参数为空，3不需要扣除
// */
//function save_dispatch_insurance($dispatch_id,$order_id,$insurance_amount){
//    if(!$dispatch_id || !$order_id || !$insurance_amount)//参数为空
//        return 2;
//
//    $order_db = M('order');
//    $counts = $order_db->where('dispatch_id = '.$dispatch_id." and DATE_FORMAT(order_time,'%Y-%m-%d') = '".date('Y-m-d',time())."' and status !=9")->count();
//
//    if($counts == 0){//需要扣除  6指每天的保险费
//        $ret_detail = pnOrderDetail($dispatch_id, $insurance_amount, 6, date('Y-m-d H:i:s',time()).'第一次接单扣除保险金额'.$insurance_amount.'元', $order_id, '保险费');//跑客钱包明细表
//
//        if (!$ret_detail)//钱包余额插入失败 2：指是跑客类型
//            return 0;
//        $ret = update_user_dispatch_blance($dispatch_id, 2, $insurance_amount*-1);
//        if($ret == 1){
//            $msg_ret = create_dispatch_message($dispatch_id,'扣除保险','每天首次接单扣除保险费'.$insurance_amount.'元','每天首次接单扣除保险费'.$insurance_amount.'元');
//            return $msg_ret;
//        }else
//            return $ret;
//    }else{//不需要需要扣除保险
//        return 3;
//    }
//}
///**
// * 每天跑客接第一单被退款，退还保险费
// *
// * @param $dispatch_id 跑客id 必填
// * @param $order_id 订单id 必填
// * @param $insurance_amount 保险金额 必填
// * @return int 0插入数据出错，1：扣除保险费成功，2：参数为空，3不需要扣除
// */
//function return_dispatch_insurance($dispatch_id,$order_id,$insurance_amount){
//    if(!$dispatch_id || !$order_id || !$insurance_amount)//参数为空
//        return 2;
//
//    $order_db = M('order');
//    $counts = $order_db->where('dispatch_id = '.$dispatch_id." and DATE_FORMAT(order_time,'%Y-%m-%d') = '".date('Y-m-d',time())."' and status !=9 ")->count();
//
//    if($counts == 1){//需要退还 9指退还保险金额
//        $ret_detail = pnOrderDetail($dispatch_id, $insurance_amount,9, date('Y-m-d H:i:s',time()).'您今天接的第一个订单被取消，退还保险金额'.$insurance_amount.'元', $order_id, '保险费');
//
//        if (!$ret_detail)//钱包余额插入失败
//            return 0;
//        $ret = update_user_dispatch_blance($dispatch_id, 2, $insurance_amount);
//        if($ret == 1){
//            $msg_ret = create_dispatch_message($dispatch_id,'退还保险金额','您今天接的第一个订单被取消，退还保险金额'.$insurance_amount.'元','您今天接的第一个订单被取消，退还保险金额'.$insurance_amount.'元');
//            return $msg_ret;
//        }else
//            return $ret;
//    }else{//不需要需要扣除保险
//        return 3;
//    }
//}
/**
 * 每天跑客接第一单时，扣除保险费  $insurance_type=6
 * 每天跑客接第一单被退款，退还保险费 $insurance_type=9
 * @param $dispatch_id 跑客id 必填
 * @param $order_id 订单id 必填
 * @param $insurance_amount 保险金额 必填
 * @return int 0插入数据出错，1：扣除保险费成功，2：参数为空，3不需要扣除
 */
function dispatch_insurance_options($dispatch_id,$order_id,$insurance_amount,$insurance_type,$titel,$infor,$content){
    if(!$dispatch_id || !$order_id || !$insurance_amount)//参数为空
        return 2;

    if($insurance_type != 6  && $insurance_type != 9 )//参数为空 6:首单扣保险费，9退保险费
        return 2;

    $order_db = M('order');
    $order_obj = $order_db->where('order_id='.$order_id.' and status >=1 and status < 7 ')->find();
    $counts = $order_db->where("dispatch_id = ".$dispatch_id." and DATE_FORMAT(order_time,'%Y-%m-%d') ='".date('Y-m-d',strtotime($order_obj['order_time']))."' and status !=9 ")->count();
    $compare_count = '0';
    if($insurance_type == 9 )
        $compare_count = '1';
//    dump($order_db->getLastSql());
//    dump('真实数='.$counts);
//    dump('比较数='.$compare_count);

    if($counts == $compare_count){//需要退还 9指退还金额
        $ret_detail = pnOrderDetail($dispatch_id, $insurance_amount,$insurance_type, $content, $order_id,$titel);

        if (!$ret_detail)//钱包余额插入失败
            return 0;
        $ret = update_user_dispatch_blance($dispatch_id, 2, $insurance_amount);
        if($ret == 1){
            $msg_ret = create_dispatch_message($dispatch_id,$titel,$infor,$content);
            return $msg_ret;
        }else
            return $ret;
    }else{//不需要需要扣除保险
        return 3;
    }
}

/**
 * 根据经纬度和城市id获取订单的跑腿费
 *  order_amount = 根据距离计算的跑腿费 + 夜间加价金额 + 临时加价金额
 * @param $startLat 开始纬度 必填
 * @param $startLng 开始经度 必填
 * @param $endLat 结束纬度 必填
 * @param $endLng 结束经度 必填
 * @param $city_id 城市id 必填
 * @param totalPrice总费用
 * @param startmoney起步价
 * @param money里程费
 * @param nightAdd夜间加价
 * @param addPrice临时加价
 * @param coupon_value 优惠券价格
 * @return string|void
 */
function get_order_money($startLat,$startLng,$endLat,$endLng,$city_id)
{
    //接口权限校验
    if(!$startLat || !$startLng || !$endLat || !$endLng || !$city_id  )
        return 0;
    $start = $startLat . "," . $startLng;
    $end = $endLat . "," . $endLng;
    //$start = '34.8029730000,113.6080970000';
    // $end = '34.8161290000,113.6193080000';
    $ret = line_uu($start, $end);
    //获取公里数取整
    $distance = $ret['message'];
    //获取公里数取整
    $kilometre = number_format($distance / 1000,2);
    //$duration = $ret['result']['routes'][0]['duration'];
    //$duration = number_format($duration / 60,2);
    //$data['duration'] = $duration;
    $cityId = (float)$city_id;
    $twoStartKiloMoney = getTwoStartKiloMoney($cityId, $kilometre);
    $totalPrice=$twoStartKiloMoney['totalPrice'];
    $data['totalPrice'] = format_money($totalPrice);

    $data['totalkilometre'] = $kilometre;

    $pricing_tactics = M('pricing_tactics');
    //夜间加价
    $nightAdd = 0;
    $ret = $pricing_tactics->where(array('city_id' => $cityId))->field('tactics_array')->find();
//    ["startkilometres"] => string(1) "3"
//    ["startmoney"] => string(1) "9"
//    ["totalPrice"] => float(14)
//    ["money"] => float(5)
//    ["kilometres"] => float(3)
    if ($ret['tactics_array']) {
        $tactics_array = json_decode($ret['tactics_array'], TRUE);
        $mileage = $tactics_array['mileage'];
        $night = $tactics_array['night'];
        $data['startkilometres'] = format_money($twoStartKiloMoney['startkilometres']);
        $data['startmoney'] = format_money($twoStartKiloMoney['startmoney']);
        $data['kilometres'] = 0.00;
        if($kilometre - format_money($twoStartKiloMoney['startkilometres']) > 0.00 )
            $data['kilometres'] = $kilometre - format_money($twoStartKiloMoney['startkilometres']);

        $data['money'] = format_money($twoStartKiloMoney['money']);
        $data['nightAdd'] = format_money($nightAdd);
        $date = null;
        /*$time = "2016-1-10 23:23";
        $date = substr($time,-5,5);
        dump($date);*/
        if (I('appointmentTime')) {
            $date = substr(I('appointmentTime'), -5, 5);
        } else {
            $date = date('H:i');
        }
        for ($i = 0; $i < count($night); $i++) {
            $startTime = $night[$i]['startTime'];
            $endTime = $night[$i]['endTime'];
            if ($startTime <= $date) {
                if ($endTime > $date) {
                    $nightAdd += $night[$i]['addMoney'];
                    $data['nightAdd'] = format_money($nightAdd);
                    $totalPrice += $nightAdd;
                    break;
                }
            }
        }
        $temporary = $tactics_array['temporary'];
//            dump($temporary);
        $addPrice = number_format($totalPrice * ($temporary["addtimes"] - 1), 2);

        $data['addPrice'] = $addPrice;
        $totalPrice += $addPrice;
        $data['totalPrice'] = number_format($totalPrice, 2);
        $return = couponUse(I('uid'), $totalPrice);
        $data['userCouponId'] = $return['userCouponId'];
        $data['couponTitle'] = $return['couponTitle'];
        $data['couponMoney'] = $return['couponMoney'];
        $data['coupon_value'] = $return['coupon_value'];
        return $data;
    } else {
        return 0;
    }
}
/**
 * 计算选择优惠券
 *  order_amount = 根据距离计算的跑腿费 + 夜间加价金额 + 临时加价金额
 * @param $uid 用户 必填
 * @param $totalMoney 总金额 必填,总里程费+夜间加价+临时加价
 *
 * @return array
 *  $return['userCouponId'] = $userCouponId; //优惠券id
 * $return['couponMoney'] = $couponMoney;//优惠后总金额
 *$ return['couponTitle'] = $couponTitle;//优惠标题
 * $return['coupon_value'] = $coupon_value;//优惠券的金额
 */
function couponUse($uid,$totalMoney){
    $user_coupon = M('user_coupon');
    //======查询出来所有未被使用的优惠券
    $ret = $user_coupon->where(array('user_id'=>$uid,'is_used'=>1))->field('user_coupon_id,remark,coupon_type,coupon_value,valid_end_time,coupon_id,min_deduct_amount')->select();
//    dump($ret);
    $userCouponId = null;
    $couponId = null;
    $couponTitle = null;
    //先缓存钱数
    $tmpMoney = $totalMoney;//$totalMoney:总里程费+夜间加价+临时加价
    $couponMoney = $totalMoney;//$totalMoney:总里程费+夜间加价+临时加价

    $coupon_value = 0;
    $return['userCouponId'] = $userCouponId;//初始 null
    $return['couponMoney'] = $couponMoney;// 初始 里程费总金额
    $return['couponTitle'] = $couponTitle;//初始 null
    if($ret){
        //======使用当前时间
        $date = date('Y-m-d H:i:s');
        //======循环比较
        foreach ($ret as $item) {
            //======如果小于使用期限
            if($date<=$item['valid_end_time']) {

                //====处理优惠券类型
                switch ($item['coupon_type']){
                    //=====抵扣券处理
                    case 1:
                        if( $totalMoney < floatval($item['coupon_value'])*C('coupon_multiple'))
                            $tmpMoney = -1; //总金额 小于 优惠券的5倍 则不可使用
                        else{
                            $tmpMoney = $totalMoney - $item['coupon_value'];//总金额-优惠券金额
//                            if($tmpMoney<0){
//                                $tmpMoney = 0;
//                            }
                        }
                        //2017年01月07日11:37:07 陈亚磊注释
                        //$coupon_value = $item['coupon_value'];
                        break;
                    //=====折扣券处理
                    case 2:
                            $tmpMoney = $totalMoney * $item['coupon_value'] / 100;
                            $coupon_value = $totalMoney * (1 - $item['coupon_value']) / 100;

                        break;
                }
                if ($tmpMoney >=0 && $tmpMoney < $couponMoney){ // 相减后 小于 总金额
                    //1
                    $coupon_value = $item['coupon_value'];
                    $couponMoney = $tmpMoney;
                    $userCouponId = $item['user_coupon_id'];
                    $couponTitle = $item['remark'];
                }
            }
        }
        $return['userCouponId'] = $userCouponId;
        $return['couponMoney'] = $couponMoney;
        $return['couponTitle'] = $couponTitle;
        $return['coupon_value'] = $coupon_value;
        return $return;
    }else{
        return $return;
    }
}
/**
 *获取排队订单价格
 * 获取订单价格(起步价10元（含30分钟），每30分钟加10元)
 *  {Int} uid 用户唯一ID.
 * {String} token 用户token,每次登录都会更改.
 * {Int} cityId 城市ID.
 * {String} timeslong 排队时长.
 * {String} appointmentTime 预约时间 选填.
 *  成功返回:
 *    data:{
 *"retCode": 0,
 *"retDesc": "计算成功！",
 *"retValue": {
 *"lineUpMoney": 20.4, //总价
 *"startlineTime": 30, //起步分钟
 *"startMoney": 10,      // 起步价
 *"money": 4,           // 费用
 *"nightAdd": 5,         //夜间加价
 *"addPrice": 3.4        //临时加价
 * "couponMoney": 3.4        //优惠之后价格
 * "couponTitle": 3.4        //优惠标题
 * "CouponId": 3.4        //优惠券id
 *}
 *}
 **/

function get_line_up_money($uid,$cityId,$hour_long,$appointmentTime)
{
    $pricing_tactics = M('pricing_tactics');
    $ret = $pricing_tactics->where(array('city_id' =>$cityId))->field('tactics_array')->find();
    if ($ret['tactics_array']) {
        $tactics_array = json_decode($ret['tactics_array'], TRUE);
        $is_starting_price = $tactics_array['is_starting_price'];
        $data['startMoney'] = format_money($is_starting_price[0]['lineKoney']);
        $data['startlineTime'] = $is_starting_price[0]['lineTime'];
        $line_up = $tactics_array['line_up'];
        $night = $tactics_array['night'];
        $pricePer = $line_up[0]['pricePer'];
        $lineUpMoney = ceil($hour_long / 30) * $pricePer;

        $data['money'] = format_money($lineUpMoney - $data['startMoney']);
        $data['lineUpMoney'] = format_money($lineUpMoney);
        $nightAdd = 0;
        $data['nightAdd'] = format_money($nightAdd);
        $date = null;
        /*$time = "2016-1-10 23:23";
        $date = substr($time,-5,5);
        dump($date);*/
        if ($appointmentTime) {
            $date = substr($appointmentTime, -5, 5);
        } else {
            $date = date('H:i');
        }
        for ($i = 0; $i < count($night); $i++) {
            $startTime = $night[$i]['startTime'];
            $endTime = $night[$i]['endTime'];
            if ($startTime <= $date) {
                if ($endTime > $date) {
                    $nightAdd += $night[$i]['addMoney'];
                    $data['nightAdd'] = format_money($nightAdd);
                    $lineUpMoney += $nightAdd;
                    break;
                }
            }
        }

        $temporary = $tactics_array['temporary'];
        $addPrice = format_money($lineUpMoney * ($temporary["addtimes"] - 1));

        $data['addPriceDesc'] = $temporary['addtimes_reson'];
        $data['addPrice'] = $addPrice;
        $lineUpMoney += $addPrice;

        $return = couponUse($uid, $lineUpMoney);
        $data['lineUpMoney'] = format_money($lineUpMoney);
        $data['couponMoney'] = number_format($return['couponMoney'], 2);
        $data['couponTitle'] = $return['couponTitle'];
        $data['CouponId'] = $return['userCouponId'];
        $data['coupon_value'] = $return['coupon_value'];
        return  $data;
    } else {
        return false;
    }
}
/**
 * 30秒没有跑客接单， 重发
 *  大于30秒小于2分钟的订单，无人接单，则重发三次给所有的跑客
 * @param uid 跑客唯一ID.
 * @param token 跑客token,每次登录都会更改.
 * @param cash_account_name 提现账号名称
 * @param cash_account 提现账号,
 */
function order_repeat(){
    $resmsm_db = M('order_resmsm r');
//    dump('order_repeat查询开始：'.date('Y-m-d H:i:s',time()));
    //获取2分钟内的待分配订单，没有被接单的订单,普通订单和预约订单
    //排序：加急优先，然后根据时间倒序
    $resms = $resmsm_db->field('r.send_id,r.order_data,is_send,o.order_type')
        ->join(' left join db_order o  on o.order_id = r.order_id')
        ->where("now() - r.order_time >30 and o.status =1 and r.is_send < 3")//待分配的订单,重发次数小于4
        ->order('is_insured,r.is_send,o.order_time desc')->select();
//    dump('查询条件结果：'.date('Y-m-d H:i:s',time()));
    if (!$resms||count($resms)==0)
        return false;
//    dump($resmsm_db->getLastSql());
//    dump($resms);
//    dump('循环开始时间：'.date('Y-m-d H:i:s',time()));
    $push_data = array();
    $resmsm_db->startTrans();
    foreach ($resms as $key=>$value){
//        dump($value['order_data']);
        $resms_arr = json_decode($value['order_data'],true);

        $appoints=$resms_arr;

        $appoints['city_id']=intval($resms_arr['city_id']);
        $appoints['order_type']=intval($resms_arr['order_type']);
        $appoints['order_id']=intval($resms_arr['order_id']);
        $appoints['conveyance_id']=intval($resms_arr['conveyance_id']);
        $appoints['company_id']=intval($resms_arr['company_id']);
        $appoints['user_id']=intval($resms_arr['user_id']);
        $appoints['pay_method']=intval($resms_arr['pay_method']);
        $appoints['send_longit']=doubleval($resms_arr['send_longit']);
        $appoints['send_latit']=doubleval($resms_arr['send_latit']);
        $appoints['reci_latit']=doubleval($resms_arr['reci_latit']);
        $appoints['reci_longit']=doubleval($resms_arr['reci_longit']);
        if($resms_arr['is_reservation'])
            $appoints['is_reservation']=intval($resms_arr['is_reservation']);
        if($resms_arr['is_have_price'])
            $appoints['is_have_price']=intval($resms_arr['is_have_price']);
//        dump($appoints);
        array_push($push_data,$appoints);

        $send_count = $value['is_send']+1;
        $up_resmsm_ret = $resmsm_db->where('send_id = '.$value['send_id'])->setField(array('is_send'=>$send_count));
//        dump($resmsm_db->getLastSql());
//        dump('修改状态结果：'.$up_resmsm_ret);
        if(!$up_resmsm_ret){
            $resmsm_db ->rollback();
            return false;
        }
    }
//    dump($push_data);
//    dump('循环结束时间：'.date('Y-m-d H:i:s',time()));
    if($push_data&&count($push_data>0)){
        $resmsm_db->commit();
        return $push_data;
    }else
        return false;
}
/**
 * 30秒没有跑客接单， 重发
 *  大于30秒小于2分钟的订单，无人接单，则重发三次给所有的跑客
 * @param uid 跑客唯一ID.
 * @param token 跑客token,每次登录都会更改.
 * @param cash_account_name 提现账号名称
 * @param cash_account 提现账号,
 */
function cancle_order_repeat($order_id){
    if(!$order_id){
        return true;
    }
    $resmsm_db = M('order_resmsm r');
//    dump('order_repeat查询开始：'.date('Y-m-d H:i:s',time()));
    //获取2分钟内的待分配订单，没有被接单的订单,普通订单和预约订单
    //排序：加急优先，然后根据时间倒序
    $order_obj = $resmsm_db->where("order_id=".$order_id)->find();
//    dump('查询条件结果：'.date('Y-m-d H:i:s',time()));
//    dump($resmsm_db->getLastSql());
//    dump($resms);
    $resms_arr = json_decode($order_obj['order_data'],true);

    $appoints=$resms_arr;

    $appoints['city_id']=intval($resms_arr['city_id']);
    $appoints['order_type']=intval($resms_arr['order_type']);
    $appoints['order_id']=intval($resms_arr['order_id']);
    $appoints['conveyance_id']=intval($resms_arr['conveyance_id']);
    $appoints['company_id']=intval($resms_arr['company_id']);
    $appoints['user_id']=intval($resms_arr['user_id']);
    $appoints['pay_method']=intval($resms_arr['pay_method']);
    $appoints['send_longit']=doubleval($resms_arr['send_longit']);
    $appoints['send_latit']=doubleval($resms_arr['send_latit']);
    $appoints['reci_latit']=doubleval($resms_arr['reci_latit']);
    $appoints['reci_longit']=doubleval($resms_arr['reci_longit']);
    if($resms_arr['is_reservation'])
        $appoints['is_reservation']=intval($resms_arr['is_reservation']);
    if($resms_arr['is_have_price'])
        $appoints['is_have_price']=intval($resms_arr['is_have_price']);
//        dump($appoints);
    
    $json_order=json_encode($appoints);
//    push_server_appdata($json_order);
    return $json_order;
   
}
/**
 * 2分钟后没有跑客接单，则强制指派订单
 * 一次推出一单，下次轮询到，再发另外一单
 * @param uid 跑客唯一ID.
 * @param token 跑客token,每次登录都会更改.
 * @param cash_account_name 提现账号名称
 * @param cash_account 提现账号,
 * @return false数据库操作失败，1，成功，2，无可指派的订单
 */
function order_appoint(){
    $resmsm_db = M('order_resmsm r');

    //获取超过2分钟的待分配订单，没有被接单的订单,普通订单和预约订单
    //排序：加急优先，然后根据时间倒序
    $resms = $resmsm_db->field('r.send_id,r.order_data,is_send,o.order_type,o.order_number')
        ->join(' left join db_order o  on o.order_id = r.order_id')
        ->where("now() - r.order_time >5*60 and o.status =1 and r.is_send >=3 ")//待分配的订单
        ->order('is_insured,r.is_send,o.order_time desc')->select();
//    dump($resmsm_db->getLastSql());
//    dump($resms);
    if (!$resms||count($resms)==0)
        return 2;
//    dump($resmsm_db->getLastSql());
//    dump(count($resms));
    $push_data_arr=array();
//    dump('循环开始：'.date('Y-m-d H:i:s',time()));
    foreach ($resms as $key=>$value){
//        dump($value);
        $resms_arr = json_decode($value['order_data'],true);

        //有需要指派的订单，订单类型不一样，经纬度的起点不一样
        //取送订单经纬度附近的跑客
        $latit=$resms_arr['send_latit'];
        $longit=$resms_arr['send_longit'];
        if($resms_arr['order_type']==3){//代买、排队的经纬度附近的跑客
            $latit=$resms_arr['reci_latit'];
            $longit=$resms_arr['reci_longit'];
        }
//        dump('查询跑客开始：'.date('Y-m-d H:i:s',time()));
//        dump($resms_arr['company_id']);
        //获取附近5公里内、接受指派的、没有在进行中的、或者指定某个团队的跑客
        $near_pns = getPn_nearby($latit,$longit,$resms_arr['company_id']);
//        $near_pns['dispatch_id']=7;
//        $near_pns['mobile']='13949036223';
//        dump($near_pns);
        if(!$near_pns || !$near_pns['dispatch_id'])
            continue;
//        dump('查询跑客结束：'.date('Y-m-d H:i:s',time()));

//        array_push($push_data_arr,$resms_arr);

//        dump('事务开始：'.date('Y-m-d H:i:s',time()));
        $order_db = M('order');
        $order_db->startTrans();
//    dump($resms_arr['order_id']);
        $order_account = getOrderAccount($resms_arr['order_id'],$near_pns['dispatch_id']);//获取跑腿费
//    dump($order_account);
        //此派单员已经签约通过，进行订单更改和抢单操作
        $up_order_ret = $order_db->where(array('order_id' => $resms_arr['order_id']))->save(array(
            //更改单子的抢单状态
            'status' => 2,
            //派单员ID更新
            'dispatch_id' => $near_pns['dispatch_id'],//指派的跑客
            //更改单子抢单最后时间
            'dispatch_end_time' => date('Y-m-d H:i:s'),
            'dispatch_get_money'=>$order_account,//跑腿费
            'is_appoint' => '1'//指派单
        ));


        //更改中间表已分配
        $order_status = $resmsm_db->where(array('r.order_id'=>$resms_arr['order_id']))->save(array('r.status'=>2,'dispatch_id'=>$near_pns['dispatch_id']));

//        dump('为'.$resms_arr['order_id'].'订单指派跑客'.$near_pns['dispatch_id']);
        //每天首单扣除保险费
//        $insu_ret = save_dispatch_insurance($near_pns['dispatch_id'], $resms_arr['order_id'], 2);
//        $insu_ret = dispatch_insurance_options($near_pns['dispatch_id'],$resms_arr['order_id'],2,6,'退还保险费','您今天接的第一个订单被取消，退还保险费2.00元','您今天接的第一个订单已被取消，退还您保险费2.00元');

        //======临时取消保险====2016-12-29 19:04:14
        //$insu_ret = dispatch_insurance_options($near_pns['dispatch_id'],$resms_arr['order_id'],-2,6,'扣除保险费','每天首次接单扣除保险费2.00元','这是一个指派单，并且是您今天首次接单（'.$value['order_number'].'）扣除保险费2.00元');
//        $up_resmsm_ret=1;
//        $del_ret = 1;
//        if(0 == $resms_arr['is_reservation']){//即时单
////            $rems_db = M('order_resmsm');
////            $del_ret = $rems_db->where('order_id='.$resms_arr['order_id'].' and otype=0')->delete();
//        }else{ // 预约单
            $send_count = $value['is_send']+1;
            $up_resmsm_ret = $resmsm_db->where('send_id = '.$value['send_id'])->setField(array('dispatch_id'=>$near_pns['dispatch_id'],'is_send'=>$send_count,'status' => '2'));
//        }

        //$insu_ret=1成功，则写入用户消息$did,$title,$intro,$content,$message_id=0
        $msg_ret = create_user_message($resms_arr['user_id'],'订单已被接收','订单（'.$value['order_number'].'）已被接收','您的订单（'.$value['order_number'].'）已被跑客接收，即刻为您完成');
        $msg_dis_ret = create_dispatch_message($near_pns['dispatch_id'],'您有一个强制指派单','您有一个强制指派单（'.$value['order_number'].'）','您有一个强制指派单（'.$value['order_number'].'），请查看并尽快完成！');

        rob_order_push($resms_arr['user_id'], '订单（' . $value['order_number'] . '）已被接收',array());//跑客接单后，给用户端极光推送
        
//        dump('开始发送短信：'.date('Y-m-d H:i:s',time()));
        send_appoint_mobile($near_pns['mobile']);
        if( $msg_ret && $up_order_ret && $up_resmsm_ret && $msg_dis_ret && $order_status){
            $order_db->commit();
        }else{
            $order_db ->rollback();
            return false;
        }
    }
//    dump('循环结束'.date('Y-m-d H:i:s',time()));
//    dump($push_data_arr);
    if($push_data_arr && count($push_data_arr)>0){
        return 1;
    }else{
        return 2;
    }


}
/**
 * 指派单提醒信息
 * @param $tel 电话
 * @return int 1：发送成功，0：发送失败；2电话为空，3：用户类型为空 ，4：订单号为空
 */
function send_appoint_mobile($tel)
{
    if (!$tel) {
        return 2;
    }

    $client = new Client;
    $request = new SmsNumSend;
    $proName = "帮你跑腿";
    $msmcode = "SMS_21710207";//指派单

    // 设置请求参数
    $req = $request->setSmsTemplateCode($msmcode)
        ->setRecNum($tel)
        ->setSmsParam('')
        ->setSmsFreeSignName($proName)
        ->setSmsType('normal');

    $status = $client->execute($req);

    if ($status["alibaba_aliqin_fc_sms_num_send_response"]["result"]["success"]) {

        return 1;
    } else {
        return 0;
    }
}
/**
 * 获取3种订单的跑腿费=订单金额*（1-佣金比值/100）
 * @param $order_id 订单id
 * @return bool
 */
function getOrderAccount($order_id,$near_pns)
{
    $order = M('order');
    $dispatch = M('dispatch');
    $ret = $order->where(array('order_id' => $order_id))->field('order_type,order_amount,goods_amount,is_have_price')->find();

    if ($ret) {
        $rets = $dispatch->where(array('dispatch_id' => $near_pns))->field('dispatch_level_id,cash_balance')->find();
        if ($rets) {
            $dispatch_level = M('dispatch_level');
            $result = $dispatch_level->where(array('dispatch_level_id' => $rets['dispatch_level_id']))->field('serv_charge_rate')->find();
            $serv_charge_rate = $result['serv_charge_rate'];
            $real=$ret['order_amount'];
            if($ret['order_type']==2&&$ret['is_have_price']==1)
                $real = $ret['order_amount']-$ret['goods_amount'];
            $balance_amount = round($real * (1 - $serv_charge_rate / 100),2);
            return $balance_amount;
        }else
            return 0;
    } else {
        return 0;
    }
}
/**
 * 获取５分钟内更新过位置的、听单状态且接受指派的、附近5公里内、没有在进行中的即时单的跑客，按距离的远近、好评率排序
 * @param {Int} uid 跑客唯一ID.
 * @param {String} token 跑客token,每次登录都会更改.
 */

function getPn_nearby_oneinfo($lat,$lon,$company_id){
    $lon=doubleval($lon);
    $lat=doubleval($lat);

    $squares = returnSquarePoint($lon,$lat);
    $where = " ";
    if($company_id != 1 ){
        $where =" and d.company_id=".$company_id;
    }
    $Model = M();
    $sql = "select dispatch_id,mobile".
        //",ROUND(6378.138*2*ASIN(SQRT(POW(SIN((22.299439*PI()/180-".$lat."*PI()/180)/2),2)+COS(22.299439*PI()/180)*COS(".$lat."*PI()/180)*POW(SIN((114.173881*PI()/180-".$lon."*PI()/180)/2),2)))*1000) AS juli".
        " from db_dispatch d where  latitude>{$squares['right-bottom']['lat']} and latitude < {$squares['left-top']['lat']} and longitude > {$squares['left-top']['lng']} and longitude < {$squares['right-bottom']['lng']} ".
        " and work_status = 1 and is_accept_dispatch = 1 and is_sign=2 and account_status=1 and now()-place_up_time < 301".
        $where.
        " and  (SELECT count(dispatch_id) as count FROM db_order o WHERE o.dispatch_id =d.dispatch_id   and o.status >1 and o.status < 7 and is_reservation=0) = 0".
        " ORDER BY ROUND(6378.138*2*ASIN(SQRT(POW(SIN((latitude*PI()/180-".$lat."*PI()/180)/2),2)+COS(latitude*PI()/180)*COS(".$lat."*PI()/180)*POW(SIN((longitude*PI()/180-".$lon."*PI()/180)/2),2)))*1000),praise desc,todaytime desc".

        " limit 1";
//    dump($sql);
    $voList = $Model->query($sql);
//    dump($voList[0]['dispatch_id']);
    return $voList[0];
}
/**
 * 获取５分钟内更新过位置的、听单状态且接受指派的、附近5公里内、没有在进行中的即时单的跑客，按距离的远近、好评率排序
 * @param {Int} uid 跑客唯一ID.
 * @param {String} token 跑客token,每次登录都会更改.
 * @param $lat,$lon 订单的经纬度
 * @param $param_kilometre 要求的派单距离
 */

function getPn_nearby($lat,$lon,$company_id,$param_kilometre=3){
    $where = " ";
    if($company_id && $company_id != 1 ){
        $where =" and d.company_id=".$company_id;
    }

    $sql = "select dispatch_id,mobile,latitude,longitude".
        " from db_dispatch d where work_status = 1 and is_accept_dispatch = 1 and is_sign=2 and account_status=1 and now()-place_up_time < 301".
        $where.
        " and  (SELECT count(dispatch_id) as count FROM db_order o WHERE o.dispatch_id =d.dispatch_id   and o.status >1 and o.status < 7 and is_reservation=0) = 0".
        " ORDER BY praise desc,todaytime desc";
    $voList = M()->query($sql);
//    dump(M()->getLastSql());
//    dump($voList);
    if($voList){
        $start = $lat . "," . $lon;
//        dump("开始经纬度：".$start);
        $best_kilometre = 0;//最短距离
        $best_dispatch_id = null;//最短距离的跑客id
        $best_mobile = null;//最短距离的跑客id
        foreach ($voList as $key=>$value){
//            dump('$key = '.$key);
            $end = $value['latitude'] . "," . $value['longitude'];
            //$start = '34.8029730000,113.6080970000';
            // $end = '34.8161290000,113.6193080000';
//            dump("开始经纬度：".$start);
//            dump("结束经纬度".$end);
            $ret = line($start, $end);
            $distance = $ret['result'][0]['distance']['value'];

//            dump('订单与跑客的距离：');
//            dump($distance);
//            dump('参考距离');
//            dump($param_kilometre*1000);
            if($distance > $param_kilometre*1000)
                continue;
            if($key == 0 || $best_kilometre > $distance){
                $best_kilometre = $distance;
                $best_dispatch_id=$value['dispatch_id'];
                $best_mobile = $value['mobile'];
            }
//            dump('最佳距离：');
//            dump($best_kilometre);
//            dump('最佳距离的跑客id：');
//            dump($best_dispatch_id);
        }

        if( $best_dispatch_id ){
            $best_dis['dispatch_id']=$best_dispatch_id;
            $best_dis['mobile']=$best_mobile;
            return $best_dis;
        }else
            return false;
    }else
        return false;
}
/**
 * 获取５分钟内更新过位置的、听单状态且接受指派的、附近5公里内、没有在进行中的即时单的跑客，按距离的远近、好评率排序
 * @param {Int} uid 跑客唯一ID.
 * @param {String} token 跑客token,每次登录都会更改.
 */

function getPn_nearby_info_bak($lat,$lon,$company_id){
    $lon=doubleval($lon);
    $lat=doubleval($lat);

    $squares = returnSquarePoint($lon,$lat,3);
    $where = " ";
    if($company_id != 1 ){
        $where =" and d.company_id=".$company_id;
    }
    $Model = M();
    $sql = "select dispatch_id".
        //",ROUND(6378.138*2*ASIN(SQRT(POW(SIN((22.299439*PI()/180-".$lat."*PI()/180)/2),2)+COS(22.299439*PI()/180)*COS(".$lat."*PI()/180)*POW(SIN((114.173881*PI()/180-".$lon."*PI()/180)/2),2)))*1000) AS juli".
        " from db_dispatch d where  latitude>{$squares['right-bottom']['lat']} and latitude < {$squares['left-top']['lat']} and longitude > {$squares['left-top']['lng']} and longitude < {$squares['right-bottom']['lng']} ".
        " and work_status = 1 and is_accept_dispatch = 1 and is_sign=2  and account_status=1 and  now()-place_up_time < 301".
        $where.
        " and  (SELECT count(dispatch_id) as count FROM db_order o WHERE o.dispatch_id =d.dispatch_id   and o.status >1 and o.status < 7 and is_reservation=0) = 0".
        " ORDER BY ROUND(6378.138*2*ASIN(SQRT(POW(SIN((latitude*PI()/180-".$lat."*PI()/180)/2),2)+COS(latitude*PI()/180)*COS(".$lat."*PI()/180)*POW(SIN((longitude*PI()/180-".$lon."*PI()/180)/2),2)))*1000),praise desc";

//    dump($sql);
    $voList = $Model->query($sql);
//    dump($voList[0]['dispatch_id']);
    return $voList[0]['dispatch_id'];
}

/**
 * 创建普通用户系统信息
 * @param $uid 用户id
 * @param $title 标题
 * @param $intro 简介
 * @param $content 内容
 * @param int $message_id 消息id
 * @return int -1参数为空，0创建失败，1创建成功
 */
function create_user_message($uid,$title,$intro,$content,$message_id=0){
//    if(!$uid||!$title||!$intro||!$content)
//        return 2;
    $msg_db = M('user_message');
    $data = array(
        'user_id'=>$uid,
        'message_id'=>$message_id,
        'title'=>$title,
        'intro'=>$intro,
        'content'=>$content,
        'time'=>date('Y-m-d H:i:s',time())
    );
    $ret = $msg_db->add($data);
    if($ret)
        return 1;
    else
        return 0;
}

/**
 * 创建跑客系统信息
 * @param $uid 跑客id
 * @param $title 标题
 * @param $intro 简介
 * @param $content 内容
 * @param int $message_id 消息id
 * @return int 2参数为空，0创建失败，1创建成功
 */
function create_dispatch_message($did,$title,$intro,$content,$message_id=0){
    if(!$did||!$title||!$intro||!$content)
        return 2;

    $msg_db = M('disptch_message');
    $data = array(
        'dispatch_id'=>$did,
        'message_id'=>$message_id,
        'title'=>$title,
        'intro'=>$intro,
        'content'=>$content,
        'time'=>date('Y-m-d H:i:s',time())
    );
    $ret = $msg_db->add($data);
    if($ret)
        return 1;
    else
        return 0;
}

/**
 *计算优惠券到期时间
 * @param $coupon_key 优惠券key
 * @return $coupon_valid_end  优惠券的过期时间
 * 12.12之后用
 **/


function coupon_valid_end($coupon_key)
  {
        $coupon_info = M('coupon_info');
       //根据$coupon_key或去$coupon_value
        $effective_days = $coupon_info->where(array('coupon_key'=>$coupon_key))->getField('effective_days');
        
         //获取当前时间
        $now = date('Y-m-d',time());
     
        $coupon_valid_end = strtotime($now); 
        //计算用户的优惠券的valid_end时间
        $coupon_valid_end  = $coupon_valid_end +(($effective_days+1) * 24 * 60 *60);
        
        //格式化时间$coupon_valid_end
        $coupon_valid_end  = date('Y-m-d H:i:s',$coupon_valid_end-1);
        return  $coupon_valid_end;    
  }

/**
 * @param $user_id 用户id
 * @param $coupon_key 优惠券key
 * @return int 0领优惠券失败，1领优惠券成功，2无优惠券
 * 0：事务回滚，1,2不需要回滚事务
 */
function newuser_reward_coupon($user_id,$coupon_key,$from_orderid=0){

    $coupon_info = M("coupon_info");
    $ret = $coupon_info->where("coupon_key='".$coupon_key."' and is_push=1 and surplus_num >0")->find();
    //判断是否有已发布的优惠券
    if(!$ret)
        return 2;

    //给用户加优惠券
    $user_coupon = M("user_coupon");
    $rets = $user_coupon->where(array('user_id' =>$user_id, 'coupon_key' => $ret['coupon_key'], 'from_orderid' => $from_orderid))->find();

    if ($rets) {
        return 2;
    }
    $from_remark = "APP兑换抵扣券，金额为" .  $ret['coupon_value'] . '元';
    if( $ret['coupon_type'] == 2)
        $from_remark = "APP兑换折扣券，折扣为" . $ret['coupon_value'] . '%';
    
    $data = array(
        'coupon_type' => $ret['coupon_type'],     //优惠券类型
        'coupon_id' => $ret['coupon_id'],
        'user_id' => $user_id,    //用户id
        'coupon_value' => $ret['coupon_value'],   //数值
        'remark' => $ret['title'],   //说明
        'valid_end_time' =>  coupon_valid_end($coupon_key), //有效截至时间
        'from_remark' => $from_remark,
        'is_used' => 1,       //是否被用 1未使用2已使用
        'coupon_key' => $coupon_key,
        'add_time' => date('Y-m-d H:i:s',time()),
        'from_orderid'=>$from_orderid
        //'highest_deduct_amount'=>10   //最高抵扣金额
    );
    $ret_status = $user_coupon->add($data);//领优惠券
    if ($ret_status) {
        $ret_coupon = $coupon_info->where(array('coupon_id' => $ret['coupon_id']))->save(array('surplus_num' => ($ret['surplus_num'] - 1)));//优惠券数量-1
        if ($ret_coupon) {
            return 1;
        } else {
            return 0;
        }
    } else {
        return 0;
    }

}
/**
 * @param $user_id 用户id
 * @param $coupon_key 优惠券key
 * @return int 0领优惠券失败，1领优惠券成功，2无优惠券
 * 0：事务回滚，1,2不需要回滚事务
 *  12.12之后用
 */


function newuser_reward_coupon2($user_id,$coupon_key,$recommended_person_id=0){

    $coupon_info = M("coupon_info");
    $ret = $coupon_info->where("coupon_key='".$coupon_key."' and is_push=1 and surplus_num >0")->find();
    //判断是否有已发布的优惠券
    if(!$ret)
        return 2;

    //判断是否过期
//    if($ret['valid_end_time'] < date('Y-m-d'))
//        return 2;

    //给用户加优惠券
    $user_coupon = M("user_coupon");
    if($recommended_person_id==0)
        $rets = $user_coupon->where(array('user_id' =>$user_id, 'coupon_key' => $ret['coupon_key']))->find();
    else
        $rets = $user_coupon->where(array('user_id' =>$user_id, 'coupon_key' => $ret['coupon_key'],'recommended_person_id'=>$recommended_person_id))->find();

    if ($rets) {
        return 2;
    }
    $from_remark = "APP兑换抵扣券，金额为" .  $ret['coupon_value'] . '元';
    if( $ret['coupon_type'] == 2)
        $from_remark = "APP兑换折扣券，折扣为" . $ret['coupon_value'] . '%';
    
    $data = array(
        'coupon_type' => $ret['coupon_type'],     //优惠券类型
        'coupon_id' => $ret['coupon_id'],
        'user_id' => $user_id,    //用户id
        'coupon_value' => $ret['coupon_value'],   //数值
        'remark' => $ret['title'],   //说明
//       'valid_end_time' =>  $ret['valid_end_time'], //有效截至时间
         'valid_end_time' => coupon_valid_end($coupon_key), //有效截至时间
        'from_remark' => $from_remark,
        'is_used' => 1,       //是否被用 1未使用2已使用
        'coupon_key' => $coupon_key,
        'add_time' => date('Y-m-d H:i:s',time()),
        'recommended_person_id' => $recommended_person_id
        //'highest_deduct_amount'=>10   //最高抵扣金额
    );
    $ret_status = $user_coupon->add($data);//领优惠券
    if ($ret_status) {
        $ret_coupon = $coupon_info->where(array('coupon_id' => $ret['coupon_id']))->save(array('surplus_num' => ($ret['surplus_num'] - 1)));//优惠券数量-1
        if ($ret_coupon) {
            return 1;
        } else {
            return 0;
        }
    } else {
        return 0;
    }

}
/**
 * 根据用户ID获取用户手机号
 * @param $uid 用户ID
 * @$utype 用户类型1：普通用户2跑客
 * @return mixed
 *
 */
function getUserMobileForType($uid, $utype)
{
    $ret = null;
    if ($utype == 1) {
        $app_users = M("app_users");
        $ret = $app_users->where(array('user_id' => $uid))->field('mobile')->find();
    }
    if ($utype == 2) {
        $app_users = M("dispatch");
        $ret = $app_users->where(array('dispatch_id' => $uid))->field('mobile')->find();
    }
    return $ret['mobile'];
}

function getOrderTypeName($order_type){

    if($order_type==1)
        return '取送订单';
    elseif ($order_type==2)
        return '代买订单';
    elseif ($order_type == 3 )
        return '代排队订单';
    else
        return '';
}
/**
 * 预约单 发送给用户和跑客，短信
 * 目前的处理，预约单提前10分钟发送短信给跑客和用户，如果需要删除，再修改
 * @param {Int} uid 跑客唯一ID.
 * @param {String} token 跑客token,每次登录都会更改.
 */
function order_reservation_msm()
{
//    dump('进入方法：'.date('Y-m-d H:i:s',time()));
    $resmsm_db = M('order_resmsm r');
    $now_timer = strtotime('now');//获取当前时间的时间戳
    $setMinute = C('remind_minute');
    $minutes = $setMinute * 60;//时间戳减10分钟，配置文件中的设置,秒
    $tm_timer = $now_timer + $minutes;//提前10分钟的时间
    $start_timer = date('Y-m-d H:i:s',$tm_timer-60*2);//在十分钟的前后两分钟内提醒，开始时间
    $end_timer = date('Y-m-d H:i:s',$tm_timer + 60*2);//在十分钟的前后两分钟内提醒,结束时间
//    dump('查询条件准备好了：'.date('Y-m-d H:i:s',time()));

//        dump($end_timer);
//        dump($start_timer);
    $resms = $resmsm_db->field('r.send_id,r.is_success,r.is_send,r.order_number,o.order_type,o.send_mobile as userTel,du.mobile as dispathTel,o.replace_mobile,o.dispatch_id')
        ->join('db_order o on o.order_id = r.order_id')
        ->join('db_dispatch du on du.dispatch_id = o.dispatch_id')
        ->where("is_success = 0 and otype=1 and o.status=2 and r.reservation_time >='" . $start_timer . "' and  r.reservation_time <='" . $end_timer . "'")
        ->select();
//        dump(date('Y-m-d H:i:s',time())."::".$resmsm_db->getLastSql());
//        dump($resms);
//    dump('查询结束：'.date('Y-m-d H:i:s',time()));
    if (!$resms)
        return;
//    dump('循环开始：'.date('Y-m-d H:i:s',time()));
    $resmsm_db->startTrans();
    $i=1;
    foreach ($resms as $value) {
//        dump('第'.$i.'次循环开始：'.date('Y-m-d H:i:s',time()));
        $userTel = $value['usertel'];
        if($value['order_type']==3)
            $userTel = $value['replace_mobile'];

        $dispatchTel = $value['dispathtel'];
        $order_number = $value['order_number'];

        send_resmsm($userTel, '1', $order_number);//成功后，返回值是null
        send_resmsm($dispatchTel, '2', $order_number);

        $now_time = date('Y-m-d H-i-s', time());
        $resms['send_time']=$now_time;
        $data = array('is_send' => $value['is_send']+1, 'is_success' => '1', 'send_time' => $now_time);
        $res_ret = $resmsm_db->where('send_id = ' . $value['send_id'])->setField($data);
        if(!$res_ret){
            $resmsm_db->rollback();
            return 0;
        }
        $i++;
    }
    $resmsm_db->commit();
//    dump('循环结束：'.date('Y-m-d H:i:s',time()));
    return $resms;
}
/**
 * 发送预约提醒信息
 * @param $tel 电话
 * @param $userType 用户类型
 * @param $ordernum 订单号
 * @return int 1：发送成功，0：发送失败；2电话为空，3：用户类型为空 ，4：订单号为空
 */
function send_resmsm($tel, $userType, $ordernum)
{
    if (!$tel) {
        return 2;
    }
    if (!$userType || !is_numeric($userType) || intval($userType) > 3 || intval($userType) < 1) {
        return 3;
    }
    if (!$ordernum)
        return 4;

    $client = new Client;
    $request = new SmsNumSend;
    $proName = "帮你跑腿";
    $msmcode = "SMS_21755279";//跑腿SMS_13280395

    if ($userType && $userType == 2)
        $msmcode = "SMS_13300476";

    // 短信内容参数
    $smsParams = array(
        'ordernum' => $ordernum,
    );

    // 设置请求参数
    $req = $request->setSmsTemplateCode($msmcode)
        ->setRecNum($tel)
        ->setSmsParam(json_encode($smsParams))
        ->setSmsFreeSignName($proName)
        ->setSmsType('normal');

    $status = $client->execute($req);

    if ($status["alibaba_aliqin_fc_sms_num_send_response"]["result"]["success"]) {

        return 1;
    } else {
        return 0;
    }
}

/**
 * 添加平台收入记录
 * @param $user_id 用户id
 * @param $dispatch_id 跑客id
 * @param $order_money 收入金额
 * @param $order_id 订单id
 * @param $income_type 收入类型：1:分成收入，2：罚用户，3：罚跑客
 * @return bool|mixed
 */
function create_systrunover($user_id,$dispatch_id,$order_money,$total_income,$order_id,$income_type,$remark,$separate_income=0.00){
    if(!$user_id && !$dispatch_id)
        return false;
    $platform_data = array(
        'uid' => $user_id,
        'dispatch_id' => $dispatch_id,
        'ordermoney' => $order_money,
        'total_income' => $total_income,
        'separate_income' => $separate_income,
        'time' => date('Y-m-d H-i-s', time()),
        'orderid' => $order_id,
        'remark' => $remark,
        'income_type' => $income_type
    );

    $systurnover_db = M('systurnover');
    $systurnover_ret = $systurnover_db->add($platform_data);
    return $systurnover_ret;
}

/**
 * 用户钱包明细表增加一条记录
 * @param $dispatch_id
 * @param $amount
 * @param $order_id
 * @param $remark
 * @return bool|mixed
 */
function create_dispatch_balance($dispatch_id,$balance_type,$amount,$order_id,$remark){
    if(!$dispatch_id || !$amount)
        return false;
    $dis_cancle_fine=C('dis_cancle_fine');//跑客退单罚款
    $data = array(
        'balance_type' => $balance_type,
        'dispatch_id' => $dispatch_id,
        'balance_amount' => $amount,
        'time' => date('Y-m-d H-i-s', time()),
        'change_memo' => $remark,
        'order_id' => $order_id,
        'remark' => $remark,
        'sum_amount'=>get_dispatch_balance($dispatch_id)+$amount
    );
    $dispatch_balance_db = M('dispatch_balance');
    $ret_add = $dispatch_balance_db->add($data);
    return $ret_add;
}

/**
 * 跑客接单后，到达前，跑客取消订单，综合处理方法
 * 1）支付违约金（跑客余额表）
 * 2）跑客余额 扣减 违约金
 * 3）违约金入账平台
 * 4）通知跑客支付违约金
 * 5）跑客金天首单已扣除保险费，用户退单需要退回保险费。
 * 6）通知跑客退还保险金
 * @param $dispatch_id 跑客id
 * @param $user_id  订单用户id
 * @param $order_id 订单id
 * @param $order_amount 订单金额（平台收入表有个订单金额字段）
 */
function pnCancleOrderOptions($dispatch_id,$user_id,$order_id,$order_amount,$order_number){
    //1、跑客余额表新增一条记录，跑客余额字段扣减5元，
    $dis_cancle_fine=C('dis_cancle_fine');//跑客取消单违约金
//  dump('罚款金额：'.$dis_cancle_fine);
    $balance_ret = create_dispatch_balance($dispatch_id,8,$dis_cancle_fine*-1,$order_id,'您自主取消一个任务（'.$order_number.'），支付违约金'.$dis_cancle_fine.'元');//跑客钱包明细表新增记录
//  dump('跑客钱包表新增结果：'.$balance_ret);
    $ub_ret = update_user_dispatch_blance($dispatch_id, 2, $dis_cancle_fine*-1);//跑客表余额字段 扣减
//  dump('跑客表余额字段 扣减结果：'.$ub_ret);
    $sys_ret = create_systrunover($user_id,$dispatch_id,$order_amount,$dis_cancle_fine,$order_id,'3',$dispatch_id.'跑客违约金');//罚金记入平台
//  dump('罚金记入平台结果：'.$ub_ret);
    //2、通知跑客支付违约金
    $msg_ret = create_dispatch_message($dispatch_id,'取消订单违约金',"取消订单违约金",'您自主取消一个任务（'.$order_number.'），支付违约金'.$dis_cancle_fine.'元');
//  dump('跑客罚金通知结果：'.$msg_ret);
    //跑客金天首单已扣除保险费，用户退单需要退回保险费。
//    $insu_ret = return_dispatch_insurance($dispatch_id, $order_id, 2);
    //========临时取消保险==============2016-12-29 19:09:32
    //$insu_ret = dispatch_insurance_options($dispatch_id,$order_id,2,9,'退还保险费','您今天接的第一个订单（'.$order_number.'）已被用户取消，退还保险费2.00元','您今天接的第一个订单（'.$order_number.'）已被用户取消，退还您保险费2.00元');
//    dump('用户退单需要退回保险费结果：'.$insu_ret);
    //退还保险金通知跑客
//    $return_insurance_msg=1;
//    if( $insu_ret == 1 ){//保险退成功了，通知跑客
//        $return_insurance_msg = create_dispatch_message($dispatch_id,'您今天接的第一个订单已被您取消',"您今天接的第一个订单已被您取消",'您今天接的第一单订单已被您取消，退还您保险费2.00元');
//    }

//    dump('退还保险金通知跑客结果：'.$return_insurance_msg);
    if($balance_ret && $ub_ret && $sys_ret && $msg_ret){
        return true;
    }else{
        return false;
    }
}

/**
 * 根据付款方式，退款
 * @param $pay_method 1、支付宝，2，微信，3，钱包
 * @param $order_number 订单号
 * @param $pay_number 支付号
 * @param $user_id 订单用户id
 * @param $order_id 订单id
 * @param $return_amount 退款金额
 * @param $remark3 第三方退款备注
 * @param $remark_msg 消息备注
 */
function return_amount_option($pay_method,$order_number,$pay_number,$user_id,$order_id,$return_amount,$remark3,$remark_msg){

    $return_ret=1;
    $purse_ret=1;
    $msg_ret=1;

    switch ($pay_method) {
        case 1://支付宝退款
            $return_ret = returnMoney($order_number, $pay_number, $return_amount, $remark3,'BNPT_'.rand(000000,999999));//执行支付宝退款
            \Think\Log::record('支付宝退款：');
            \Think\Log::record($return_ret);
            $purse_ret = userPurseLog($user_id, 3, $return_amount, $remark_msg, 0, $order_id);//用户钱包明细表 增加记录
//                      dump('用户钱包明细表'.$return_amount . '元');
//                    dump($purse_ret);
            $msg_ret = create_user_message($user_id,$remark_msg);
//            dump('用户消息：'.$return_amount . '元');
//                    dump($msg_ret);
            break;
        case 2:break;//微信退款
        case 3://钱包余额退款（用户表余额字段值增加，用户钱包明细表增加明细记录）
            $return_ret =1;
            $purse_ret = 1;
            if(floatval($return_amount) != 0.00){

//            dump('用户表余额字段值增加'.$return_amount . '元');
//            dump($return_ret);
                $purse_ret = userPurseLog($user_id, 3, $return_amount,$remark_msg, 0, $order_id);//用户钱包明细表 增加记录
                $return_ret = update_user_dispatch_blance($user_id, 1,$return_amount);//增加 用户表或跑客表的 余额字段  的值
//              dump('用户钱包明细表'.$return_amount . '元');
//                dump($purse_ret);
            }

            $msg_ret = create_user_message($user_id,'取消订单',$remark_msg,$remark_msg);
//            dump('用户消息：'.$return_amount . '元');
//            dump($msg_ret);
            break;
    }
    if($return_ret && $purse_ret && $msg_ret ){
        return true;
    }else{
        return false;
    }
}

/**
 * 审核成功、失败提醒短信
 * @param $tel 电话
 * @param $auditResult 2成功，3失败
 * @param $reason 失败理由
 * @return int 1：发送成功，0：发送失败；2参数为空
 */
function send_audit_sms($tel, $auditResult, $reason)
{
    if (!$tel || !$auditResult || $auditResult < 2 ) {
        return 2;
    }

    $client = new Client;
    $request = new SmsNumSend;
    $proName = "帮你跑腿";
    $msmcode = "SMS_34455054";//审核通过情况

    $smsParams='';
    if ($auditResult == 3){
        $msmcode = "SMS_24845266";//审核失败
        // 短信内容参数
        $params = array(
            'reason' => $reason,
        );
        $smsParams = json_encode($params);
    }

    // 设置请求参数
    $req = $request->setSmsTemplateCode($msmcode)
        ->setRecNum($tel)
        ->setSmsParam($smsParams)
        ->setSmsFreeSignName($proName)
        ->setSmsType('normal');

    $status = $client->execute($req);

    if ($status["alibaba_aliqin_fc_sms_num_send_response"]["result"]["success"]) {

        return 1;
    } else {
        return 0;
    }
}
/**
 * 订单完成提醒短信
 * @param $tel 电话
 * @param $auditResult 2成功，3失败
 * @param $reason 失败理由
 * @return int 1：发送成功，0：发送失败；2参数为空
 */
function send_order_finish_sms($tel, $order_number)
{
    if (!$tel || !$order_number ) {
        return 2;
    }

    $client = new Client;
    $request = new SmsNumSend;
    $proName = "帮你跑腿";
    $msmcode = "SMS_34465254";

    // 短信内容参数
    $params = array(
        'order' => $order_number,
    );
    $smsParams = json_encode($params);

    // 设置请求参数
    $req = $request->setSmsTemplateCode($msmcode)
        ->setRecNum($tel)
        ->setSmsParam($smsParams)
        ->setSmsFreeSignName($proName)
        ->setSmsType('normal');

    $status = $client->execute($req);

    if ($status["alibaba_aliqin_fc_sms_num_send_response"]["result"]["success"]) {

        return 1;
    } else {
        return 0;
    }
}
/**
 * 发送推广短信广告
 * 信息
 * @param $tel 电话
 * @param $msmcode 短信模板代码
 * @return
 */
function send_market_mobile($tel,$msmcode)
{
    if (!$tel || !$msmcode) {
        return 2;
    }

    $client = new Client('23478892','1fba58f6ecd25e8e67e12f51f2203326');
    $request = new SmsNumSend;
    $proName = "帮你跑腿";
//    $msmcode = "SMS_21710207";//指派单

    // 设置请求参数
    $req = $request->setSmsTemplateCode($msmcode)
        ->setRecNum($tel)
        ->setSmsParam('')
        ->setSmsFreeSignName($proName)
        ->setSmsType('normal');

    $status = $client->execute($req);

    if ($status["alibaba_aliqin_fc_sms_num_send_response"]["result"]["success"]) {

        return 1;
    } else {
        return 0;
    }
}

/**
 * 增加积分
 * @param $points array('user_id'=>,'points_type'=>,'points_value'=>,'remark'=>,'from_id'=>)
 */
function addPoints($points){
    if(!$points|| !$points['user_id'])
        return 2;
    $user_db = M('app_users');
    $user_obj = $user_db->field('user_id,points_value')->where(array('user_id'=>$points['user_id']))->find();

    $points['points_time']=date('Y-m-d H:i:s',time());
    if( $user_obj ){
        $user_points_db = M('user_points');
        $add_ret = $user_points_db->add($points);

        $points_value = $points['points_value']+$user_obj['points_value'];
        $user_save_ret = $user_db->where(array('user_id'=>$points['user_id']))->save(array('points_value'=>$points_value));

        if($add_ret && $user_save_ret){
            return 1;
        }else
            return 0;
    }else
        return 2;
}


function conveyance($conveyance_id){
    $conveyance = M("conveyance");
    $ret = $conveyance->where(array('conveyance_id'=>$conveyance_id))->field('conv_name')->find();
    return $ret['conv_name'];
}

/**
 * 跑客接单后，给下单人极光推送
 * @param $user_id
 */
function rob_order_push($user_id,$content,$extras){
    //极光推送 start
    $jpush_ret = M('app_users')->field('jpush_id')->where('user_id='.$user_id)->find();
    import("Vendor.Jpush.ptJpush");
    $jpush = new \ptJpush();//用户推送
    $jpush_ret = $jpush->push(array('registration_id' =>array( $jpush_ret['jpush_id'])), '', $content,$extras);//推送操作
    //极光推送 end
}

/**
 * 优惠券是否用
 * 不存在，被使用，过期的优惠券，均是无效的优惠券
 * @param $coupon_id  db_user_coupon 主键id
 * @param $user_id 用户id
 * @return bool true可用，false不可用
 */
function isvalid_used_coupon($user_coupon_id,$user_id){
    if(!$user_coupon_id || !$user_id)
        return false;
    $user_coupon_db = M('user_coupon');
    $user_coupon_obj = $user_coupon_db->where(array('user_coupon_id' => $user_coupon_id, 'user_id' => $user_id,'is_used'=>1))->find();

    if(!$user_coupon_obj)
        return false;

    if(strtotime($user_coupon_obj['valid_end_time']) < time())
        return false;
    else
        return true;
}

/**
 * 手机号归属地查询
 * @param tel 要查询的手机号
 */
function serach_tel_location($tel){
    //没有传递手机号传递false
    if(empty($tel)){
        return false;
    }
    $tel = "http://apis.juhe.cn/mobile/get?phone=".$tel."&dtype=&key=74641cd35c065cc9190a3a10382a79f0";
    $ch = curl_init($tel);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $cexeCute = curl_exec($ch);
    curl_close($ch);
    return json_decode($cexeCute,true);
}


//========================令牌校验==========================
/**
 * 创建TOKEN
 */
function creatToken() {
    $code = chr(mt_rand(0xB0, 0xF7)) . chr(mt_rand(0xA1, 0xFE)) . chr(mt_rand(0xB0, 0xF7)) . chr(mt_rand(0xA1, 0xFE)) . chr(mt_rand(0xB0, 0xF7)) . chr(mt_rand(0xA1, 0xFE));
    session('TOKEN', authcode($code));
}

/**
 * 判断TOKEN
 * @param $token
 * @return bool
 *
 */
function checkToken($token) {
    if ($token == session('TOKEN')) {
        session('TOKEN', NULL);
        return TRUE;
    } else {
        return FALSE;
    }
}

/**
 * 加密TOKEN
 * @param $str
 * @return string
 */
function authcode($str) {
    $key = "ANDIAMON";
    $str = substr(md5($str), 8, 10);
    return md5($key . $str);
}

/**
 * 获取跑客信息表的账户余额
 * @param $dispatch_id
 * @param $this_amount
 */
function get_dispatch_balance($dispatch_id){
    $dispatch_db = M('dispatch d ');
    $dispatch = $dispatch_db->field('cash_balance')->where(array('dispatch_id'=>$dispatch_id))->find();

    if($dispatch)
        return $dispatch['cash_balance'];
    else
        return 0.00;
}
/**
 * 获取用户信息表的账户余额
 * @param $dispatch_id
 */
function get_user_balance($user_id){
    $user_db = M('app_users a ');
    $user = $user_db->field('purse_balance')->where(array('user_id'=>$user_id))->find();

    if($user)
        return $user['purse_balance'];
    else
        return 0.00;
}
/**
 * 订单派送提醒短信
 * @param $tel 电话
 * @param $auditResult 2成功，3失败
 * @param $reason 失败理由
 * @return int 1：发送成功，0：发送失败；2参数为空
 */
function send_order_sms($tel, $message)
{
    if (!$tel || !$message ) {
        return 2;
    }

    $client = new Client;
    $request = new SmsNumSend;
    $proName = "帮你跑腿";
    $msmcode = "SMS_53720158";

    // 短信内容参数
    $params = array(
        'name' => $message['dispatch_name'],
        'phone' => $message['mobile']
    );
//    
   $smsParams = json_encode($params);
    // 设置请求参数
    $req = $request->setSmsTemplateCode($msmcode)
        ->setRecNum($tel)
        ->setSmsParam($smsParams)
        ->setSmsFreeSignName($proName)
        ->setSmsType('normal');

    $status = $client->execute($req);
    if ($status["alibaba_aliqin_fc_sms_num_send_response"]["result"]["success"]) {

        return 1;
    } else {
        return 0;
    }
}